openstudio-common-measures 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test_with_openstudio.yml +1 -1
- data/CHANGELOG.md +13 -0
- data/LICENSE.md +1 -1
- data/README.md +1 -0
- data/doc_templates/LICENSE.md +1 -1
- data/lib/measures/AddCostPerAreaToConstruction/LICENSE.md +1 -1
- data/lib/measures/AddCostPerAreaToConstruction/measure.xml +3 -3
- data/lib/measures/AddCostPerFloorAreaToBuilding/LICENSE.md +1 -1
- data/lib/measures/AddCostPerFloorAreaToBuilding/measure.xml +3 -3
- data/lib/measures/AddCostPerFloorAreaToElectricEquipment/LICENSE.md +1 -1
- data/lib/measures/AddCostPerFloorAreaToElectricEquipment/measure.xml +3 -3
- data/lib/measures/AddCostPerFloorAreaToLights/LICENSE.md +1 -1
- data/lib/measures/AddCostPerFloorAreaToLights/measure.xml +3 -3
- data/lib/measures/AddCostPerFloorAreaUnusedToLights/LICENSE.md +1 -1
- data/lib/measures/AddCostPerFloorAreaUnusedToLights/measure.xml +3 -3
- data/lib/measures/AddCostToSupplySideHVACComponentByAirLoop/LICENSE.md +1 -1
- data/lib/measures/AddCostToSupplySideHVACComponentByAirLoop/measure.xml +4 -4
- data/lib/measures/AddCostperAreatoUnusedConstruction/LICENSE.md +1 -1
- data/lib/measures/AddCostperAreatoUnusedConstruction/measure.xml +3 -3
- data/lib/measures/AddExteriorLights/LICENSE.md +1 -1
- data/lib/measures/AddExteriorLights/measure.xml +3 -3
- data/lib/measures/AddMeter/LICENSE.md +1 -1
- data/lib/measures/AddMeter/measure.xml +3 -3
- data/lib/measures/AddOutputDiagnostics/LICENSE.md +1 -1
- data/lib/measures/AddOutputDiagnostics/measure.rb +1 -1
- data/lib/measures/AddOutputDiagnostics/measure.xml +5 -5
- data/lib/measures/AddOutputVariable/LICENSE.md +1 -1
- data/lib/measures/AddOutputVariable/measure.xml +3 -3
- data/lib/measures/AddSimplePvToShadingSurfacesByType/LICENSE.md +1 -1
- data/lib/measures/AddSimplePvToShadingSurfacesByType/measure.xml +3 -3
- data/lib/measures/AddThermalComfortModelTypes/LICENSE.md +1 -1
- data/lib/measures/AddThermalComfortModelTypes/measure.xml +3 -3
- data/lib/measures/AdjustSystemEfficiencies/LICENSE.md +1 -1
- data/lib/measures/AdjustSystemEfficiencies/measure.xml +3 -3
- data/lib/measures/AdjustThermostatSetpointsByDegrees/LICENSE.md +1 -1
- data/lib/measures/AdjustThermostatSetpointsByDegrees/measure.xml +3 -3
- data/lib/measures/ChangeBuildingLocation/LICENSE.md +1 -1
- data/lib/measures/ChangeBuildingLocation/measure.xml +23 -5
- data/lib/measures/ChangeBuildingLocation/resources/epw.rb +7 -2
- data/lib/measures/EnableIdealAirLoadsForAllZones/LICENSE.md +1 -1
- data/lib/measures/EnableIdealAirLoadsForAllZones/measure.xml +3 -3
- data/lib/measures/ExportScheduleCSV/LICENSE.md +1 -1
- data/lib/measures/ExportScheduleCSV/measure.xml +3 -3
- data/lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/LICENSE.md +1 -1
- data/lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.xml +3 -3
- data/lib/measures/MeterFlodPlot/LICENSE.md +1 -1
- data/lib/measures/MeterFlodPlot/measure.xml +3 -3
- data/lib/measures/ModifyEnergyPlusCoilCoolingDXSingleSpeedObjects/LICENSE.md +1 -1
- data/lib/measures/ModifyEnergyPlusCoilCoolingDXSingleSpeedObjects/measure.xml +3 -3
- data/lib/measures/ModifyEnergyPlusFanVariableVolumeObjects/LICENSE.md +1 -1
- data/lib/measures/ModifyEnergyPlusFanVariableVolumeObjects/measure.xml +3 -3
- data/lib/measures/PredictedMeanVote/LICENSE.md +1 -1
- data/lib/measures/PredictedMeanVote/measure.xml +3 -3
- data/lib/measures/RemoveInternalLoadsDirectlyAssignedToSpaces/LICENSE.md +1 -1
- data/lib/measures/RemoveInternalLoadsDirectlyAssignedToSpaces/measure.xml +3 -3
- data/lib/measures/RemoveUnusedDefaultProfiles/LICENSE.md +1 -1
- data/lib/measures/RemoveUnusedDefaultProfiles/measure.xml +3 -3
- data/lib/measures/ReplaceExteriorWindowConstruction/LICENSE.md +1 -1
- data/lib/measures/ReplaceExteriorWindowConstruction/measure.xml +3 -3
- data/lib/measures/ReplaceModel/LICENSE.md +1 -1
- data/lib/measures/ReplaceModel/measure.xml +3 -3
- data/lib/measures/ReplaceThermostatSchedules/LICENSE.md +1 -1
- data/lib/measures/ReplaceThermostatSchedules/measure.xml +5 -5
- data/lib/measures/ReportModelChanges/LICENSE.md +1 -1
- data/lib/measures/ReportModelChanges/measure.xml +3 -3
- data/lib/measures/RunPeriod/LICENSE.md +1 -1
- data/lib/measures/RunPeriod/measure.xml +3 -3
- data/lib/measures/RunPeriodMultiple/LICENSE.md +1 -1
- data/lib/measures/RunPeriodMultiple/measure.xml +3 -3
- data/lib/measures/ServerDirectoryCleanup/LICENSE.md +1 -1
- data/lib/measures/ServerDirectoryCleanup/README.md +14 -14
- data/lib/measures/ServerDirectoryCleanup/measure.rb +22 -18
- data/lib/measures/ServerDirectoryCleanup/measure.xml +25 -25
- data/lib/measures/SetCOPforSingleSpeedDXCoolingUnits/LICENSE.md +1 -1
- data/lib/measures/SetCOPforSingleSpeedDXCoolingUnits/measure.xml +5 -5
- data/lib/measures/SetCOPforTwoSpeedDXCoolingUnits/LICENSE.md +1 -1
- data/lib/measures/SetCOPforTwoSpeedDXCoolingUnits/measure.xml +5 -5
- data/lib/measures/SetEnergyPlusInfiltrationFlowRatePerFloorArea/LICENSE.md +1 -1
- data/lib/measures/SetEnergyPlusInfiltrationFlowRatePerFloorArea/measure.xml +3 -3
- data/lib/measures/SetEnergyPlusLightObjectsLPD/LICENSE.md +1 -1
- data/lib/measures/SetEnergyPlusLightObjectsLPD/measure.xml +3 -3
- data/lib/measures/SetEnergyPlusMinimumOutdoorAirFlowRate/LICENSE.md +1 -1
- data/lib/measures/SetEnergyPlusMinimumOutdoorAirFlowRate/measure.xml +3 -3
- data/lib/measures/SetGasBurnerEfficiency/LICENSE.md +1 -1
- data/lib/measures/SetGasBurnerEfficiency/measure.xml +5 -5
- data/lib/measures/SetLifecycleCostParameters/LICENSE.md +1 -1
- data/lib/measures/SetLifecycleCostParameters/measure.xml +3 -3
- data/lib/measures/SetLightingLoadsByLPD/LICENSE.md +1 -1
- data/lib/measures/SetLightingLoadsByLPD/measure.xml +5 -5
- data/lib/measures/SetSpaceInfiltrationByExteriorSurfaceArea/LICENSE.md +1 -1
- data/lib/measures/SetSpaceInfiltrationByExteriorSurfaceArea/measure.xml +3 -3
- data/lib/measures/SetThermostatSchedules/LICENSE.md +1 -1
- data/lib/measures/SetThermostatSchedules/measure.xml +5 -5
- data/lib/measures/ShiftScheduleProfileTime/LICENSE.md +1 -1
- data/lib/measures/ShiftScheduleProfileTime/measure.xml +5 -5
- data/lib/measures/SwapLightsDefinition/LICENSE.md +1 -1
- data/lib/measures/SwapLightsDefinition/measure.xml +3 -3
- data/lib/measures/UnmetLoadHoursTroubleshooting/LICENSE.md +1 -1
- data/lib/measures/UnmetLoadHoursTroubleshooting/measure.xml +3 -3
- data/lib/measures/VentilationQAQC/LICENSE.md +1 -1
- data/lib/measures/VentilationQAQC/measure.xml +3 -3
- data/lib/measures/XcelEDAReportingandQAQC/LICENSE.md +1 -1
- data/lib/measures/XcelEDAReportingandQAQC/measure.xml +3 -3
- data/lib/measures/XcelEDATariffSelectionandModelSetup/LICENSE.md +1 -1
- data/lib/measures/XcelEDATariffSelectionandModelSetup/measure.xml +3 -3
- data/lib/measures/ZoneReport/LICENSE.md +1 -1
- data/lib/measures/ZoneReport/measure.xml +3 -3
- data/lib/measures/add_ems_emissions_reporting/LICENSE.md +1 -1
- data/lib/measures/add_ems_emissions_reporting/measure.xml +3 -3
- data/lib/measures/add_ems_to_control_ev_charging/LICENSE.md +1 -1
- data/lib/measures/add_ems_to_control_ev_charging/measure.xml +3 -3
- data/lib/measures/add_ev_load/LICENSE.md +1 -1
- data/lib/measures/add_ev_load/measure.xml +3 -3
- data/lib/measures/add_rooftop_pv/LICENSE.md +1 -1
- data/lib/measures/add_rooftop_pv/measure.xml +3 -3
- data/lib/measures/add_zone_mixing_object/LICENSE.md +1 -1
- data/lib/measures/add_zone_mixing_object/measure.xml +3 -3
- data/lib/measures/add_zone_ventilation_design_flow_rate_object/LICENSE.md +1 -1
- data/lib/measures/add_zone_ventilation_design_flow_rate_object/measure.xml +3 -3
- data/lib/measures/air_wall_zone_mixing/LICENSE.md +1 -1
- data/lib/measures/air_wall_zone_mixing/measure.xml +3 -3
- data/lib/measures/create_csv_output/LICENSE.md +1 -1
- data/lib/measures/create_csv_output/measure.xml +3 -3
- data/lib/measures/envelope_and_internal_load_breakdown/LICENSE.md +1 -1
- data/lib/measures/envelope_and_internal_load_breakdown/measure.xml +3 -3
- data/lib/measures/example_report/LICENSE.md +1 -1
- data/lib/measures/example_report/measure.xml +3 -3
- data/lib/measures/gem_env_report/LICENSE.md +1 -1
- data/lib/measures/gem_env_report/measure.xml +3 -3
- data/lib/measures/generic_qaqc/LICENSE.md +1 -1
- data/lib/measures/generic_qaqc/README.md +0 -32
- data/lib/measures/generic_qaqc/measure.rb +5 -2
- data/lib/measures/generic_qaqc/measure.xml +5 -61
- data/lib/measures/get_site_from_building_component_library/LICENSE.md +1 -1
- data/lib/measures/get_site_from_building_component_library/measure.xml +3 -3
- data/lib/measures/hvac_psychrometric_chart/LICENSE.md +1 -1
- data/lib/measures/hvac_psychrometric_chart/measure.xml +3 -3
- data/lib/measures/inject_idf_objects/LICENSE.md +1 -1
- data/lib/measures/inject_idf_objects/measure.xml +3 -3
- data/lib/measures/openstudio_results/LICENSE.md +1 -1
- data/lib/measures/openstudio_results/README.md +10 -2
- data/lib/measures/openstudio_results/measure.rb +19 -7
- data/lib/measures/openstudio_results/measure.xml +80 -21
- data/lib/measures/openstudio_results/resources/Siz.AirConditionerVariableRefrigerantFlow.rb +1 -1
- data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXMultiSpeed.rb +10 -0
- data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXMultiSpeedStageData.rb +3 -1
- data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXSingleSpeed.rb +2 -2
- data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXTwoSpeed.rb +4 -3
- data/lib/measures/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpEquationFit.rb +6 -0
- data/lib/measures/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.rb +10 -0
- data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXMultiSpeed.rb +10 -0
- data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXSingleSpeed.rb +1 -1
- data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpEquationFit.rb +6 -0
- data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.rb +10 -0
- data/lib/measures/openstudio_results/resources/Siz.CoilPerformanceDXCooling.rb +1 -1
- data/lib/measures/openstudio_results/resources/Siz.FanSystemModel.rb +31 -0
- data/lib/measures/openstudio_results/resources/Siz.Model.rb +1 -0
- data/lib/measures/openstudio_results/resources/bootstrap.min.css +5 -0
- data/lib/measures/openstudio_results/resources/bootstrap.min.js +6 -0
- data/lib/measures/openstudio_results/resources/d3.min.js +5 -0
- data/lib/measures/openstudio_results/resources/dimple.v2.1.2.min.js +3 -0
- data/lib/measures/openstudio_results/resources/jquery.min.js +6 -0
- data/lib/measures/openstudio_results/resources/os_lib_reporting.rb +12 -0
- data/lib/measures/openstudio_results/resources/report.html.erb +5 -5
- data/lib/measures/remove_orphan_objects_and_unused_resources/LICENSE.md +1 -1
- data/lib/measures/remove_orphan_objects_and_unused_resources/measure.xml +3 -3
- data/lib/measures/set_electric_equipment_loads_by_epd/LICENSE.md +1 -1
- data/lib/measures/set_electric_equipment_loads_by_epd/measure.xml +5 -5
- data/lib/measures/set_exterior_walls_and_floors_to_adiabatic/LICENSE.md +1 -1
- data/lib/measures/set_exterior_walls_and_floors_to_adiabatic/measure.xml +3 -3
- data/lib/measures/set_run_period/LICENSE.md +1 -1
- data/lib/measures/set_run_period/measure.xml +3 -3
- data/lib/measures/set_space_infiltration_per_exterior_area/LICENSE.md +1 -1
- data/lib/measures/set_space_infiltration_per_exterior_area/README.md +11 -0
- data/lib/measures/set_space_infiltration_per_exterior_area/measure.rb +13 -0
- data/lib/measures/set_space_infiltration_per_exterior_area/measure.xml +24 -5
- data/lib/measures/shadow_calculation/LICENSE.md +1 -1
- data/lib/measures/shadow_calculation/measure.xml +3 -3
- data/lib/measures/simulation_control/README.md +120 -0
- data/lib/measures/simulation_control/README.md.erb +42 -0
- data/lib/measures/simulation_control/measure.rb +169 -0
- data/lib/measures/simulation_control/measure.xml +246 -0
- data/lib/measures/tariff_selection_block/LICENSE.md +1 -1
- data/lib/measures/tariff_selection_block/measure.xml +3 -3
- data/lib/measures/tariff_selection_flat/LICENSE.md +1 -1
- data/lib/measures/tariff_selection_flat/measure.xml +3 -3
- data/lib/measures/tariff_selection_generic/LICENSE.md +1 -1
- data/lib/measures/tariff_selection_generic/measure.xml +3 -3
- data/lib/measures/tariff_selection_time_and_date_dependant/LICENSE.md +1 -1
- data/lib/measures/tariff_selection_time_and_date_dependant/measure.xml +3 -3
- data/lib/measures/view_data/LICENSE.md +1 -1
- data/lib/measures/view_data/README.md +8 -0
- data/lib/measures/view_data/measure.rb +32 -7
- data/lib/measures/view_data/measure.xml +50 -7
- data/lib/measures/view_data/resources/js/TweenLite.2.1.3.min.js +12 -0
- data/lib/measures/view_data/resources/js/dat.gui.0.7.9.min.js +13 -0
- data/lib/measures/view_data/resources/js/three.orbitcontrols.js +706 -0
- data/lib/measures/view_data/resources/js/three.r98.min.js +964 -0
- data/lib/measures/view_data/resources/report.html.in +170 -1837
- data/lib/measures/view_model/LICENSE.md +1 -1
- data/lib/measures/view_model/README.md +7 -1
- data/lib/measures/view_model/measure.rb +28 -2
- data/lib/measures/view_model/measure.xml +52 -8
- data/lib/measures/view_model/resources/js/TweenLite.2.1.3.min.js +12 -0
- data/lib/measures/view_model/resources/js/dat.gui.0.7.9.min.js +13 -0
- data/lib/measures/view_model/resources/js/three.orbitcontrols.js +706 -0
- data/lib/measures/view_model/resources/js/three.r98.min.js +964 -0
- data/lib/measures/view_model/resources/report.html.in +168 -1835
- data/lib/openstudio/common_measures/version.rb +1 -1
- data/openstudio-common-measures.gemspec +2 -3
- metadata +25 -21
@@ -0,0 +1,706 @@
|
|
1
|
+
/**
|
2
|
+
* @author qiao / https://github.com/qiao
|
3
|
+
* @author mrdoob / http://mrdoob.com
|
4
|
+
* @author alteredq / http://alteredqualia.com/
|
5
|
+
* @author WestLangley / http://github.com/WestLangley
|
6
|
+
* @author erich666 / http://erichaines.com
|
7
|
+
*/
|
8
|
+
/*global THREE, console */
|
9
|
+
|
10
|
+
// This set of controls performs orbiting, dollying (zooming), and panning. It maintains
|
11
|
+
// the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is
|
12
|
+
// supported.
|
13
|
+
//
|
14
|
+
// Orbit - left mouse / touch: one finger move
|
15
|
+
// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
|
16
|
+
// Pan - right mouse, or arrow keys / touch: three finter swipe
|
17
|
+
|
18
|
+
THREE.OrbitControls = function ( object, domElement ) {
|
19
|
+
|
20
|
+
this.object = object;
|
21
|
+
this.domElement = ( domElement !== undefined ) ? domElement : document;
|
22
|
+
|
23
|
+
// API
|
24
|
+
|
25
|
+
// Set to false to disable this control
|
26
|
+
this.enabled = true;
|
27
|
+
|
28
|
+
// "target" sets the location of focus, where the control orbits around
|
29
|
+
// and where it pans with respect to.
|
30
|
+
this.target = new THREE.Vector3();
|
31
|
+
|
32
|
+
// center is old, deprecated; use "target" instead
|
33
|
+
this.center = this.target;
|
34
|
+
|
35
|
+
// This option actually enables dollying in and out; left as "zoom" for
|
36
|
+
// backwards compatibility
|
37
|
+
this.noZoom = false;
|
38
|
+
this.zoomSpeed = 1.0;
|
39
|
+
|
40
|
+
// Limits to how far you can dolly in and out ( PerspectiveCamera only )
|
41
|
+
this.minDistance = 0;
|
42
|
+
this.maxDistance = Infinity;
|
43
|
+
|
44
|
+
// Limits to how far you can zoom in and out ( OrthographicCamera only )
|
45
|
+
this.minZoom = 0;
|
46
|
+
this.maxZoom = Infinity;
|
47
|
+
|
48
|
+
// Set to true to disable this control
|
49
|
+
this.noRotate = false;
|
50
|
+
this.rotateSpeed = 1.0;
|
51
|
+
|
52
|
+
// Set to true to disable this control
|
53
|
+
this.noPan = false;
|
54
|
+
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
|
55
|
+
|
56
|
+
// Set to true to automatically rotate around the target
|
57
|
+
this.autoRotate = false;
|
58
|
+
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
|
59
|
+
|
60
|
+
// How far you can orbit vertically, upper and lower limits.
|
61
|
+
// Range is 0 to Math.PI radians.
|
62
|
+
this.minPolarAngle = 0; // radians
|
63
|
+
this.maxPolarAngle = Math.PI; // radians
|
64
|
+
|
65
|
+
// How far you can orbit horizontally, upper and lower limits.
|
66
|
+
// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
|
67
|
+
this.minAzimuthAngle = - Infinity; // radians
|
68
|
+
this.maxAzimuthAngle = Infinity; // radians
|
69
|
+
|
70
|
+
// Set to true to disable use of the keys
|
71
|
+
this.noKeys = false;
|
72
|
+
|
73
|
+
// The four arrow keys
|
74
|
+
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
|
75
|
+
|
76
|
+
// Mouse buttons
|
77
|
+
this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
|
78
|
+
|
79
|
+
////////////
|
80
|
+
// internals
|
81
|
+
|
82
|
+
var scope = this;
|
83
|
+
|
84
|
+
var EPS = 0.000001;
|
85
|
+
|
86
|
+
var rotateStart = new THREE.Vector2();
|
87
|
+
var rotateEnd = new THREE.Vector2();
|
88
|
+
var rotateDelta = new THREE.Vector2();
|
89
|
+
|
90
|
+
var panStart = new THREE.Vector2();
|
91
|
+
var panEnd = new THREE.Vector2();
|
92
|
+
var panDelta = new THREE.Vector2();
|
93
|
+
var panOffset = new THREE.Vector3();
|
94
|
+
|
95
|
+
var offset = new THREE.Vector3();
|
96
|
+
|
97
|
+
var dollyStart = new THREE.Vector2();
|
98
|
+
var dollyEnd = new THREE.Vector2();
|
99
|
+
var dollyDelta = new THREE.Vector2();
|
100
|
+
|
101
|
+
var theta;
|
102
|
+
var phi;
|
103
|
+
var phiDelta = 0;
|
104
|
+
var thetaDelta = 0;
|
105
|
+
var scale = 1;
|
106
|
+
var pan = new THREE.Vector3();
|
107
|
+
|
108
|
+
var lastPosition = new THREE.Vector3();
|
109
|
+
var lastQuaternion = new THREE.Quaternion();
|
110
|
+
|
111
|
+
var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
|
112
|
+
|
113
|
+
var state = STATE.NONE;
|
114
|
+
|
115
|
+
// for reset
|
116
|
+
|
117
|
+
this.target0 = this.target.clone();
|
118
|
+
this.position0 = this.object.position.clone();
|
119
|
+
this.zoom0 = this.object.zoom;
|
120
|
+
|
121
|
+
// so camera.up is the orbit axis
|
122
|
+
|
123
|
+
var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
|
124
|
+
var quatInverse = quat.clone().inverse();
|
125
|
+
|
126
|
+
// events
|
127
|
+
|
128
|
+
var changeEvent = { type: 'change' };
|
129
|
+
var startEvent = { type: 'start' };
|
130
|
+
var endEvent = { type: 'end' };
|
131
|
+
|
132
|
+
this.rotateLeft = function ( angle ) {
|
133
|
+
|
134
|
+
if ( angle === undefined ) {
|
135
|
+
|
136
|
+
angle = getAutoRotationAngle();
|
137
|
+
|
138
|
+
}
|
139
|
+
|
140
|
+
thetaDelta -= angle;
|
141
|
+
|
142
|
+
};
|
143
|
+
|
144
|
+
this.rotateUp = function ( angle ) {
|
145
|
+
|
146
|
+
if ( angle === undefined ) {
|
147
|
+
|
148
|
+
angle = getAutoRotationAngle();
|
149
|
+
|
150
|
+
}
|
151
|
+
|
152
|
+
phiDelta -= angle;
|
153
|
+
|
154
|
+
};
|
155
|
+
|
156
|
+
// pass in distance in world space to move left
|
157
|
+
this.panLeft = function ( distance ) {
|
158
|
+
|
159
|
+
var te = this.object.matrix.elements;
|
160
|
+
|
161
|
+
// get X column of matrix
|
162
|
+
panOffset.set( te[ 0 ], te[ 1 ], te[ 2 ] );
|
163
|
+
panOffset.multiplyScalar( - distance );
|
164
|
+
|
165
|
+
pan.add( panOffset );
|
166
|
+
|
167
|
+
};
|
168
|
+
|
169
|
+
// pass in distance in world space to move up
|
170
|
+
this.panUp = function ( distance ) {
|
171
|
+
|
172
|
+
var te = this.object.matrix.elements;
|
173
|
+
|
174
|
+
// get Y column of matrix
|
175
|
+
panOffset.set( te[ 4 ], te[ 5 ], te[ 6 ] );
|
176
|
+
panOffset.multiplyScalar( distance );
|
177
|
+
|
178
|
+
pan.add( panOffset );
|
179
|
+
|
180
|
+
};
|
181
|
+
|
182
|
+
// pass in x,y of change desired in pixel space,
|
183
|
+
// right and down are positive
|
184
|
+
this.pan = function ( deltaX, deltaY ) {
|
185
|
+
|
186
|
+
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
187
|
+
|
188
|
+
if ( scope.object instanceof THREE.PerspectiveCamera ) {
|
189
|
+
|
190
|
+
// perspective
|
191
|
+
var position = scope.object.position;
|
192
|
+
var offset = position.clone().sub( scope.target );
|
193
|
+
var targetDistance = offset.length();
|
194
|
+
|
195
|
+
// half of the fov is center to top of screen
|
196
|
+
targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
|
197
|
+
|
198
|
+
// we actually don't use screenWidth, since perspective camera is fixed to screen height
|
199
|
+
scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight );
|
200
|
+
scope.panUp( 2 * deltaY * targetDistance / element.clientHeight );
|
201
|
+
|
202
|
+
} else if ( scope.object instanceof THREE.OrthographicCamera ) {
|
203
|
+
|
204
|
+
// orthographic
|
205
|
+
scope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth );
|
206
|
+
scope.panUp( deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight );
|
207
|
+
|
208
|
+
} else {
|
209
|
+
|
210
|
+
// camera neither orthographic or perspective
|
211
|
+
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
|
212
|
+
|
213
|
+
}
|
214
|
+
|
215
|
+
};
|
216
|
+
|
217
|
+
this.dollyIn = function ( dollyScale ) {
|
218
|
+
|
219
|
+
if ( dollyScale === undefined ) {
|
220
|
+
|
221
|
+
dollyScale = getZoomScale();
|
222
|
+
|
223
|
+
}
|
224
|
+
|
225
|
+
if ( scope.object instanceof THREE.PerspectiveCamera ) {
|
226
|
+
|
227
|
+
scale /= dollyScale;
|
228
|
+
|
229
|
+
} else if ( scope.object instanceof THREE.OrthographicCamera ) {
|
230
|
+
|
231
|
+
scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom * dollyScale ) );
|
232
|
+
scope.object.updateProjectionMatrix();
|
233
|
+
scope.dispatchEvent( changeEvent );
|
234
|
+
|
235
|
+
} else {
|
236
|
+
|
237
|
+
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
|
238
|
+
|
239
|
+
}
|
240
|
+
|
241
|
+
};
|
242
|
+
|
243
|
+
this.dollyOut = function ( dollyScale ) {
|
244
|
+
|
245
|
+
if ( dollyScale === undefined ) {
|
246
|
+
|
247
|
+
dollyScale = getZoomScale();
|
248
|
+
|
249
|
+
}
|
250
|
+
|
251
|
+
if ( scope.object instanceof THREE.PerspectiveCamera ) {
|
252
|
+
|
253
|
+
scale *= dollyScale;
|
254
|
+
|
255
|
+
} else if ( scope.object instanceof THREE.OrthographicCamera ) {
|
256
|
+
|
257
|
+
scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / dollyScale ) );
|
258
|
+
scope.object.updateProjectionMatrix();
|
259
|
+
scope.dispatchEvent( changeEvent );
|
260
|
+
|
261
|
+
} else {
|
262
|
+
|
263
|
+
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
|
264
|
+
|
265
|
+
}
|
266
|
+
|
267
|
+
};
|
268
|
+
|
269
|
+
this.update = function () {
|
270
|
+
|
271
|
+
var position = this.object.position;
|
272
|
+
|
273
|
+
offset.copy( position ).sub( this.target );
|
274
|
+
|
275
|
+
// rotate offset to "y-axis-is-up" space
|
276
|
+
offset.applyQuaternion( quat );
|
277
|
+
|
278
|
+
// angle from z-axis around y-axis
|
279
|
+
|
280
|
+
theta = Math.atan2( offset.x, offset.z );
|
281
|
+
|
282
|
+
// angle from y-axis
|
283
|
+
|
284
|
+
phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
|
285
|
+
|
286
|
+
if ( this.autoRotate && state === STATE.NONE ) {
|
287
|
+
|
288
|
+
this.rotateLeft( getAutoRotationAngle() );
|
289
|
+
|
290
|
+
}
|
291
|
+
|
292
|
+
theta += thetaDelta;
|
293
|
+
phi += phiDelta;
|
294
|
+
|
295
|
+
// restrict theta to be between desired limits
|
296
|
+
theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) );
|
297
|
+
|
298
|
+
// restrict phi to be between desired limits
|
299
|
+
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
|
300
|
+
|
301
|
+
// restrict phi to be betwee EPS and PI-EPS
|
302
|
+
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
|
303
|
+
|
304
|
+
var radius = offset.length() * scale;
|
305
|
+
|
306
|
+
// restrict radius to be between desired limits
|
307
|
+
radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
|
308
|
+
|
309
|
+
// move target to panned location
|
310
|
+
this.target.add( pan );
|
311
|
+
|
312
|
+
offset.x = radius * Math.sin( phi ) * Math.sin( theta );
|
313
|
+
offset.y = radius * Math.cos( phi );
|
314
|
+
offset.z = radius * Math.sin( phi ) * Math.cos( theta );
|
315
|
+
|
316
|
+
// rotate offset back to "camera-up-vector-is-up" space
|
317
|
+
offset.applyQuaternion( quatInverse );
|
318
|
+
|
319
|
+
position.copy( this.target ).add( offset );
|
320
|
+
|
321
|
+
this.object.lookAt( this.target );
|
322
|
+
|
323
|
+
thetaDelta = 0;
|
324
|
+
phiDelta = 0;
|
325
|
+
scale = 1;
|
326
|
+
pan.set( 0, 0, 0 );
|
327
|
+
|
328
|
+
// update condition is:
|
329
|
+
// min(camera displacement, camera rotation in radians)^2 > EPS
|
330
|
+
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
|
331
|
+
|
332
|
+
if ( lastPosition.distanceToSquared( this.object.position ) > EPS
|
333
|
+
|| 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) {
|
334
|
+
|
335
|
+
this.dispatchEvent( changeEvent );
|
336
|
+
|
337
|
+
lastPosition.copy( this.object.position );
|
338
|
+
lastQuaternion.copy (this.object.quaternion );
|
339
|
+
|
340
|
+
}
|
341
|
+
|
342
|
+
};
|
343
|
+
|
344
|
+
|
345
|
+
this.reset = function () {
|
346
|
+
|
347
|
+
state = STATE.NONE;
|
348
|
+
|
349
|
+
this.target.copy( this.target0 );
|
350
|
+
this.object.position.copy( this.position0 );
|
351
|
+
this.object.zoom = this.zoom0;
|
352
|
+
|
353
|
+
this.object.updateProjectionMatrix();
|
354
|
+
this.dispatchEvent( changeEvent );
|
355
|
+
|
356
|
+
this.update();
|
357
|
+
|
358
|
+
};
|
359
|
+
|
360
|
+
this.getPolarAngle = function () {
|
361
|
+
|
362
|
+
return phi;
|
363
|
+
|
364
|
+
};
|
365
|
+
|
366
|
+
this.getAzimuthalAngle = function () {
|
367
|
+
|
368
|
+
return theta
|
369
|
+
|
370
|
+
};
|
371
|
+
|
372
|
+
function getAutoRotationAngle() {
|
373
|
+
|
374
|
+
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
|
375
|
+
|
376
|
+
}
|
377
|
+
|
378
|
+
function getZoomScale() {
|
379
|
+
|
380
|
+
return Math.pow( 0.95, scope.zoomSpeed );
|
381
|
+
|
382
|
+
}
|
383
|
+
|
384
|
+
function onMouseDown( event ) {
|
385
|
+
|
386
|
+
if ( scope.enabled === false ) return;
|
387
|
+
event.preventDefault();
|
388
|
+
|
389
|
+
if ( event.button === scope.mouseButtons.ORBIT ) {
|
390
|
+
if ( scope.noRotate === true ) return;
|
391
|
+
|
392
|
+
state = STATE.ROTATE;
|
393
|
+
|
394
|
+
rotateStart.set( event.clientX, event.clientY );
|
395
|
+
|
396
|
+
} else if ( event.button === scope.mouseButtons.ZOOM ) {
|
397
|
+
if ( scope.noZoom === true ) return;
|
398
|
+
|
399
|
+
state = STATE.DOLLY;
|
400
|
+
|
401
|
+
dollyStart.set( event.clientX, event.clientY );
|
402
|
+
|
403
|
+
} else if ( event.button === scope.mouseButtons.PAN ) {
|
404
|
+
if ( scope.noPan === true ) return;
|
405
|
+
|
406
|
+
state = STATE.PAN;
|
407
|
+
|
408
|
+
panStart.set( event.clientX, event.clientY );
|
409
|
+
|
410
|
+
}
|
411
|
+
|
412
|
+
if ( state !== STATE.NONE ) {
|
413
|
+
document.addEventListener( 'mousemove', onMouseMove, false );
|
414
|
+
document.addEventListener( 'mouseup', onMouseUp, false );
|
415
|
+
scope.dispatchEvent( startEvent );
|
416
|
+
}
|
417
|
+
|
418
|
+
}
|
419
|
+
|
420
|
+
function onMouseMove( event ) {
|
421
|
+
|
422
|
+
if ( scope.enabled === false ) return;
|
423
|
+
|
424
|
+
event.preventDefault();
|
425
|
+
|
426
|
+
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
427
|
+
|
428
|
+
if ( state === STATE.ROTATE ) {
|
429
|
+
|
430
|
+
if ( scope.noRotate === true ) return;
|
431
|
+
|
432
|
+
rotateEnd.set( event.clientX, event.clientY );
|
433
|
+
rotateDelta.subVectors( rotateEnd, rotateStart );
|
434
|
+
|
435
|
+
// rotating across whole screen goes 360 degrees around
|
436
|
+
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
|
437
|
+
|
438
|
+
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
439
|
+
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
|
440
|
+
|
441
|
+
rotateStart.copy( rotateEnd );
|
442
|
+
|
443
|
+
} else if ( state === STATE.DOLLY ) {
|
444
|
+
|
445
|
+
if ( scope.noZoom === true ) return;
|
446
|
+
|
447
|
+
dollyEnd.set( event.clientX, event.clientY );
|
448
|
+
dollyDelta.subVectors( dollyEnd, dollyStart );
|
449
|
+
|
450
|
+
if ( dollyDelta.y > 0 ) {
|
451
|
+
|
452
|
+
scope.dollyIn();
|
453
|
+
|
454
|
+
} else if ( dollyDelta.y < 0 ) {
|
455
|
+
|
456
|
+
scope.dollyOut();
|
457
|
+
|
458
|
+
}
|
459
|
+
|
460
|
+
dollyStart.copy( dollyEnd );
|
461
|
+
|
462
|
+
} else if ( state === STATE.PAN ) {
|
463
|
+
|
464
|
+
if ( scope.noPan === true ) return;
|
465
|
+
|
466
|
+
panEnd.set( event.clientX, event.clientY );
|
467
|
+
panDelta.subVectors( panEnd, panStart );
|
468
|
+
|
469
|
+
scope.pan( panDelta.x, panDelta.y );
|
470
|
+
|
471
|
+
panStart.copy( panEnd );
|
472
|
+
|
473
|
+
}
|
474
|
+
|
475
|
+
if ( state !== STATE.NONE ) scope.update();
|
476
|
+
|
477
|
+
}
|
478
|
+
|
479
|
+
function onMouseUp( /* event */ ) {
|
480
|
+
|
481
|
+
if ( scope.enabled === false ) return;
|
482
|
+
|
483
|
+
document.removeEventListener( 'mousemove', onMouseMove, false );
|
484
|
+
document.removeEventListener( 'mouseup', onMouseUp, false );
|
485
|
+
scope.dispatchEvent( endEvent );
|
486
|
+
state = STATE.NONE;
|
487
|
+
|
488
|
+
}
|
489
|
+
|
490
|
+
function onMouseWheel( event ) {
|
491
|
+
|
492
|
+
if ( scope.enabled === false || scope.noZoom === true || state !== STATE.NONE ) return;
|
493
|
+
|
494
|
+
event.preventDefault();
|
495
|
+
event.stopPropagation();
|
496
|
+
|
497
|
+
var delta = 0;
|
498
|
+
|
499
|
+
if ( event.wheelDelta !== undefined ) { // WebKit / Opera / Explorer 9
|
500
|
+
|
501
|
+
delta = event.wheelDelta;
|
502
|
+
|
503
|
+
} else if ( event.detail !== undefined ) { // Firefox
|
504
|
+
|
505
|
+
delta = - event.detail;
|
506
|
+
|
507
|
+
}
|
508
|
+
|
509
|
+
if ( delta > 0 ) {
|
510
|
+
|
511
|
+
scope.dollyOut();
|
512
|
+
|
513
|
+
} else if ( delta < 0 ) {
|
514
|
+
|
515
|
+
scope.dollyIn();
|
516
|
+
|
517
|
+
}
|
518
|
+
|
519
|
+
scope.update();
|
520
|
+
scope.dispatchEvent( startEvent );
|
521
|
+
scope.dispatchEvent( endEvent );
|
522
|
+
|
523
|
+
}
|
524
|
+
|
525
|
+
function onKeyDown( event ) {
|
526
|
+
|
527
|
+
if ( scope.enabled === false || scope.noKeys === true || scope.noPan === true ) return;
|
528
|
+
|
529
|
+
switch ( event.keyCode ) {
|
530
|
+
|
531
|
+
case scope.keys.UP:
|
532
|
+
scope.pan( 0, scope.keyPanSpeed );
|
533
|
+
scope.update();
|
534
|
+
break;
|
535
|
+
|
536
|
+
case scope.keys.BOTTOM:
|
537
|
+
scope.pan( 0, - scope.keyPanSpeed );
|
538
|
+
scope.update();
|
539
|
+
break;
|
540
|
+
|
541
|
+
case scope.keys.LEFT:
|
542
|
+
scope.pan( scope.keyPanSpeed, 0 );
|
543
|
+
scope.update();
|
544
|
+
break;
|
545
|
+
|
546
|
+
case scope.keys.RIGHT:
|
547
|
+
scope.pan( - scope.keyPanSpeed, 0 );
|
548
|
+
scope.update();
|
549
|
+
break;
|
550
|
+
|
551
|
+
}
|
552
|
+
|
553
|
+
}
|
554
|
+
|
555
|
+
function touchstart( event ) {
|
556
|
+
|
557
|
+
if ( scope.enabled === false ) return;
|
558
|
+
|
559
|
+
switch ( event.touches.length ) {
|
560
|
+
|
561
|
+
case 1: // one-fingered touch: rotate
|
562
|
+
|
563
|
+
if ( scope.noRotate === true ) return;
|
564
|
+
|
565
|
+
state = STATE.TOUCH_ROTATE;
|
566
|
+
|
567
|
+
rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
568
|
+
break;
|
569
|
+
|
570
|
+
case 2: // two-fingered touch: dolly
|
571
|
+
|
572
|
+
if ( scope.noZoom === true ) return;
|
573
|
+
|
574
|
+
state = STATE.TOUCH_DOLLY;
|
575
|
+
|
576
|
+
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
|
577
|
+
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
|
578
|
+
var distance = Math.sqrt( dx * dx + dy * dy );
|
579
|
+
dollyStart.set( 0, distance );
|
580
|
+
break;
|
581
|
+
|
582
|
+
case 3: // three-fingered touch: pan
|
583
|
+
|
584
|
+
if ( scope.noPan === true ) return;
|
585
|
+
|
586
|
+
state = STATE.TOUCH_PAN;
|
587
|
+
|
588
|
+
panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
589
|
+
break;
|
590
|
+
|
591
|
+
default:
|
592
|
+
|
593
|
+
state = STATE.NONE;
|
594
|
+
|
595
|
+
}
|
596
|
+
|
597
|
+
if ( state !== STATE.NONE ) scope.dispatchEvent( startEvent );
|
598
|
+
|
599
|
+
}
|
600
|
+
|
601
|
+
function touchmove( event ) {
|
602
|
+
|
603
|
+
if ( scope.enabled === false ) return;
|
604
|
+
|
605
|
+
event.preventDefault();
|
606
|
+
event.stopPropagation();
|
607
|
+
|
608
|
+
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
609
|
+
|
610
|
+
switch ( event.touches.length ) {
|
611
|
+
|
612
|
+
case 1: // one-fingered touch: rotate
|
613
|
+
|
614
|
+
if ( scope.noRotate === true ) return;
|
615
|
+
if ( state !== STATE.TOUCH_ROTATE ) return;
|
616
|
+
|
617
|
+
rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
618
|
+
rotateDelta.subVectors( rotateEnd, rotateStart );
|
619
|
+
|
620
|
+
// rotating across whole screen goes 360 degrees around
|
621
|
+
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
|
622
|
+
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
623
|
+
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
|
624
|
+
|
625
|
+
rotateStart.copy( rotateEnd );
|
626
|
+
|
627
|
+
scope.update();
|
628
|
+
break;
|
629
|
+
|
630
|
+
case 2: // two-fingered touch: dolly
|
631
|
+
|
632
|
+
if ( scope.noZoom === true ) return;
|
633
|
+
if ( state !== STATE.TOUCH_DOLLY ) return;
|
634
|
+
|
635
|
+
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
|
636
|
+
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
|
637
|
+
var distance = Math.sqrt( dx * dx + dy * dy );
|
638
|
+
|
639
|
+
dollyEnd.set( 0, distance );
|
640
|
+
dollyDelta.subVectors( dollyEnd, dollyStart );
|
641
|
+
|
642
|
+
if ( dollyDelta.y > 0 ) {
|
643
|
+
|
644
|
+
scope.dollyOut();
|
645
|
+
|
646
|
+
} else if ( dollyDelta.y < 0 ) {
|
647
|
+
|
648
|
+
scope.dollyIn();
|
649
|
+
|
650
|
+
}
|
651
|
+
|
652
|
+
dollyStart.copy( dollyEnd );
|
653
|
+
|
654
|
+
scope.update();
|
655
|
+
break;
|
656
|
+
|
657
|
+
case 3: // three-fingered touch: pan
|
658
|
+
|
659
|
+
if ( scope.noPan === true ) return;
|
660
|
+
if ( state !== STATE.TOUCH_PAN ) return;
|
661
|
+
|
662
|
+
panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
663
|
+
panDelta.subVectors( panEnd, panStart );
|
664
|
+
|
665
|
+
scope.pan( panDelta.x, panDelta.y );
|
666
|
+
|
667
|
+
panStart.copy( panEnd );
|
668
|
+
|
669
|
+
scope.update();
|
670
|
+
break;
|
671
|
+
|
672
|
+
default:
|
673
|
+
|
674
|
+
state = STATE.NONE;
|
675
|
+
|
676
|
+
}
|
677
|
+
|
678
|
+
}
|
679
|
+
|
680
|
+
function touchend( /* event */ ) {
|
681
|
+
|
682
|
+
if ( scope.enabled === false ) return;
|
683
|
+
|
684
|
+
scope.dispatchEvent( endEvent );
|
685
|
+
state = STATE.NONE;
|
686
|
+
|
687
|
+
}
|
688
|
+
|
689
|
+
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
|
690
|
+
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
|
691
|
+
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
|
692
|
+
this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
|
693
|
+
|
694
|
+
this.domElement.addEventListener( 'touchstart', touchstart, false );
|
695
|
+
this.domElement.addEventListener( 'touchend', touchend, false );
|
696
|
+
this.domElement.addEventListener( 'touchmove', touchmove, false );
|
697
|
+
|
698
|
+
window.addEventListener( 'keydown', onKeyDown, false );
|
699
|
+
|
700
|
+
// force an update at start
|
701
|
+
this.update();
|
702
|
+
|
703
|
+
};
|
704
|
+
|
705
|
+
THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
|
706
|
+
THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;
|