How to use cos_direction_and_y_axis method in wpt

Best JavaScript code snippet using wpt

webxr-test.js

Source:webxr-test.js Github

copy

Full Screen

1'use strict';2// This polyfill library implements the WebXR Test API as specified here:3// https://github.com/immersive-web/webxr-test-api4const default_standing = new gfx.mojom.Transform();5default_standing.matrix = [1, 0, 0, 0,6 0, 1, 0, 0,7 0, 0, 1, 0,8 0, 1.65, 0, 1];9const default_stage_parameters = {10 standingTransform: default_standing,11 bounds: null12};13function getMatrixFromTransform(transform) {14 const x = transform.orientation[0];15 const y = transform.orientation[1];16 const z = transform.orientation[2];17 const w = transform.orientation[3];18 const m11 = 1.0 - 2.0 * (y * y + z * z);19 const m21 = 2.0 * (x * y + z * w);20 const m31 = 2.0 * (x * z - y * w);21 const m12 = 2.0 * (x * y - z * w);22 const m22 = 1.0 - 2.0 * (x * x + z * z);23 const m32 = 2.0 * (y * z + x * w);24 const m13 = 2.0 * (x * z + y * w);25 const m23 = 2.0 * (y * z - x * w);26 const m33 = 1.0 - 2.0 * (x * x + y * y);27 const m14 = transform.position[0];28 const m24 = transform.position[1];29 const m34 = transform.position[2];30 // Column-major linearized order is expected.31 return [m11, m21, m31, 0,32 m12, m22, m32, 0,33 m13, m23, m33, 0,34 m14, m24, m34, 1];35}36function composeGFXTransform(fakeTransformInit) {37 const transform = new gfx.mojom.Transform();38 transform.matrix = getMatrixFromTransform(fakeTransformInit);39 return transform;40}41class ChromeXRTest {42 constructor() {43 this.mockVRService_ = new MockVRService(mojo.frameInterfaces);44 }45 simulateDeviceConnection(init_params) {46 return Promise.resolve(this.mockVRService_.addRuntime(init_params));47 }48 disconnectAllDevices() {49 this.mockVRService_.removeAllRuntimes(device);50 return Promise.resolve();51 }52 simulateUserActivation(callback) {53 const button = document.createElement('button');54 button.textContent = 'click to continue test';55 button.style.display = 'block';56 button.style.fontSize = '20px';57 button.style.padding = '10px';58 button.onclick = () => {59 callback();60 document.body.removeChild(button);61 };62 document.body.appendChild(button);63 test_driver.click(button);64 }65}66// Mocking class definitions67// Mock service implements the VRService mojo interface.68class MockVRService {69 constructor() {70 this.bindingSet_ = new mojo.BindingSet(device.mojom.VRService);71 this.runtimes_ = [];72 this.interceptor_ =73 new MojoInterfaceInterceptor(device.mojom.VRService.name);74 this.interceptor_.oninterfacerequest = e =>75 this.bindingSet_.addBinding(this, e.handle);76 this.interceptor_.start();77 }78 // Test methods79 addRuntime(fakeDeviceInit) {80 const runtime = new MockRuntime(fakeDeviceInit, this);81 this.runtimes_.push(runtime);82 if (this.client_) {83 this.client_.onDeviceChanged();84 }85 return runtime;86 }87 removeAllRuntimes() {88 if (this.client_) {89 this.client_.onDeviceChanged();90 }91 this.runtimes_ = [];92 }93 removeRuntime(device) {94 const index = this.runtimes_.indexOf(device);95 if (index >= 0) {96 this.runtimes_.splice(index, 1);97 if (this.client_) {98 this.client_.onDeviceChanged();99 }100 }101 }102 setClient(client) {103 if (this.client_) {104 throw new Error("setClient should only be called once");105 }106 this.client_ = client;107 }108 requestSession(sessionOptions, was_activation) {109 const requests = [];110 // Request a session from all the runtimes.111 for (let i = 0; i < this.runtimes_.length; i++) {112 requests[i] = this.runtimes_[i].requestRuntimeSession(sessionOptions);113 }114 return Promise.all(requests).then((results) => {115 // Find and return the first successful result.116 for (let i = 0; i < results.length; i++) {117 if (results[i].session) {118 // Construct a dummy metrics recorder119 const metricsRecorderPtr = new device.mojom.XRSessionMetricsRecorderPtr();120 const metricsRecorderRequest = mojo.makeRequest(metricsRecorderPtr);121 const metricsRecorderBinding = new mojo.Binding(122 device.mojom.XRSessionMetricsRecorder, new MockXRSessionMetricsRecorder(), metricsRecorderRequest);123 const success = {124 session: results[i].session,125 metricsRecorder: metricsRecorderPtr,126 };127 return {128 result: {129 success : success,130 $tag : 0131 }132 };133 }134 }135 // If there were no successful results, returns a null session.136 return {137 result: {138 failureReason : device.mojom.RequestSessionError.NO_RUNTIME_FOUND,139 $tag : 1140 }141 };142 });143 }144 exitPresent() {145 return Promise.resolve();146 }147 supportsSession(sessionOptions) {148 const requests = [];149 // Check supports on all the runtimes.150 for (let i = 0; i < this.runtimes_.length; i++) {151 requests[i] = this.runtimes_[i].runtimeSupportsSession(sessionOptions);152 }153 return Promise.all(requests).then((results) => {154 // Find and return the first successful result.155 for (let i = 0; i < results.length; i++) {156 if (results[i].supportsSession) {157 return results[i];158 }159 }160 // If there were no successful results, returns false.161 return {supportsSession: false};162 });163 }164}165// Implements XRFrameDataProvider and XRPresentationProvider. Maintains a mock166// for XRPresentationProvider.167class MockRuntime {168 // Mapping from string feature names to the corresponding mojo types.169 // This is exposed as a member for extensibility.170 static featureToMojoMap = {171 'viewer': device.mojom.XRSessionFeature.REF_SPACE_VIEWER,172 'local': device.mojom.XRSessionFeature.REF_SPACE_LOCAL,173 'local-floor': device.mojom.XRSessionFeature.REF_SPACE_LOCAL_FLOOR,174 'bounded-floor': device.mojom.XRSessionFeature.REF_SPACE_BOUNDED_FLOOR,175 'unbounded': device.mojom.XRSessionFeature.REF_SPACE_UNBOUNDED,176 'hit-test': device.mojom.XRSessionFeature.HIT_TEST,177 'dom-overlay': device.mojom.XRSessionFeature.DOM_OVERLAY,178 };179 static sessionModeToMojoMap = {180 "inline": device.mojom.XRSessionMode.kInline,181 "immersive-vr": device.mojom.XRSessionMode.kImmersiveVr,182 "immersive-ar": device.mojom.XRSessionMode.kImmersiveAr,183 };184 constructor(fakeDeviceInit, service) {185 this.sessionClient_ = new device.mojom.XRSessionClientPtr();186 this.presentation_provider_ = new MockXRPresentationProvider();187 this.pose_ = null;188 this.next_frame_id_ = 0;189 this.bounds_ = null;190 this.send_mojo_space_reset_ = false;191 this.stageParameters_ = null;192 this.stageParametersUpdated_ = false;193 this.service_ = service;194 this.framesOfReference = {};195 this.input_sources_ = new Map();196 this.next_input_source_index_ = 1;197 // Currently active hit test subscriptons.198 this.hitTestSubscriptions_ = new Map();199 // ID of the next subscription to be assigned.200 this.next_hit_test_id_ = 1;201 let supportedModes = [];202 if (fakeDeviceInit.supportedModes) {203 supportedModes = fakeDeviceInit.supportedModes.slice();204 if (fakeDeviceInit.supportedModes.length === 0) {205 supportedModes = ["inline"];206 }207 } else {208 // Back-compat mode.209 console.warn("Please use `supportedModes` to signal which modes are supported by this device.");210 if (fakeDeviceInit.supportsImmersive == null) {211 throw new TypeError("'supportsImmersive' must be set");212 }213 supportedModes = ["inline"];214 if (fakeDeviceInit.supportsImmersive) {215 supportedModes.push("immersive-vr");216 }217 }218 this.supportedModes_ = this._convertModesToEnum(supportedModes);219 // Initialize DisplayInfo first to set the defaults, then override with220 // anything from the deviceInit221 if (this.supportedModes_.includes(device.mojom.XRSessionMode.kImmersiveVr)222 || this.supportedModes_.includes(device.mojom.XRSessionMode.kImmersiveAr)) {223 this.displayInfo_ = this.getImmersiveDisplayInfo();224 } else if (this.supportedModes_.includes(device.mojom.XRSessionMode.kInline)) {225 this.displayInfo_ = this.getNonImmersiveDisplayInfo();226 } else {227 // This should never happen!228 console.error("Device has empty supported modes array!");229 throw new InvalidStateError();230 }231 if (fakeDeviceInit.viewerOrigin != null) {232 this.setViewerOrigin(fakeDeviceInit.viewerOrigin);233 }234 if (fakeDeviceInit.floorOrigin != null) {235 this.setFloorOrigin(fakeDeviceInit.floorOrigin);236 }237 if (fakeDeviceInit.world) {238 this.world_ = fakeDeviceInit.world;239 }240 // This appropriately handles if the coordinates are null241 this.setBoundsGeometry(fakeDeviceInit.boundsCoordinates);242 this.setViews(fakeDeviceInit.views);243 // Need to support webVR which doesn't have a notion of features244 this.setFeatures(fakeDeviceInit.supportedFeatures || []);245 }246 _convertModeToEnum(sessionMode) {247 if (sessionMode in MockRuntime.sessionModeToMojoMap) {248 return MockRuntime.sessionModeToMojoMap[sessionMode];249 }250 throw new TypeError("Unrecognized value for XRSessionMode enum: " + sessionMode);251 }252 _convertModesToEnum(sessionModes) {253 return sessionModes.map(mode => this._convertModeToEnum(mode));254 }255 // Test API methods.256 disconnect() {257 this.service_.removeRuntime(this);258 this.presentation_provider_.Close();259 if (this.sessionClient_.ptr.isBound()) {260 this.sessionClient_.ptr.reset();261 }262 return Promise.resolve();263 }264 setViews(views) {265 if (views) {266 let changed = false;267 for (let i = 0; i < views.length; i++) {268 if (views[i].eye == 'left') {269 this.displayInfo_.leftEye = this.getEye(views[i]);270 changed = true;271 } else if (views[i].eye == 'right') {272 this.displayInfo_.rightEye = this.getEye(views[i]);273 changed = true;274 }275 }276 if (changed && this.sessionClient_.ptr.isBound()) {277 this.sessionClient_.onChanged(this.displayInfo_);278 }279 }280 }281 setViewerOrigin(origin, emulatedPosition = false) {282 const p = origin.position;283 const q = origin.orientation;284 this.pose_ = {285 orientation: { x: q[0], y: q[1], z: q[2], w: q[3] },286 position: { x: p[0], y: p[1], z: p[2] },287 emulatedPosition: emulatedPosition,288 angularVelocity: null,289 linearVelocity: null,290 angularAcceleration: null,291 linearAcceleration: null,292 inputState: null,293 poseIndex: 0294 };295 }296 clearViewerOrigin() {297 this.pose_ = null;298 }299 simulateVisibilityChange(visibilityState) {300 let mojoState = null;301 switch (visibilityState) {302 case "visible":303 mojoState = device.mojom.XRVisibilityState.VISIBLE;304 break;305 case "visible-blurred":306 mojoState = device.mojom.XRVisibilityState.VISIBLE_BLURRED;307 break;308 case "hidden":309 mojoState = device.mojom.XRVisibilityState.HIDDEN;310 break;311 }312 if (mojoState) {313 this.sessionClient_.onVisibilityStateChanged(mojoState);314 }315 }316 setBoundsGeometry(bounds) {317 if (bounds == null) {318 this.bounds_ = null;319 } else if (bounds.length < 3) {320 throw new Error("Bounds must have a length of at least 3");321 } else {322 this.bounds_ = bounds;323 }324 // We can only set bounds if we have stageParameters set; otherwise, we325 // don't know the transform from local space to bounds space.326 // We'll cache the bounds so that they can be set in the future if the327 // floorLevel transform is set, but we won't update them just yet.328 if (this.stageParameters_) {329 this.stageParameters_.bounds = this.bounds_;330 this.onStageParametersUpdated();331 }332 }333 setFloorOrigin(floorOrigin) {334 if (!this.stageParameters_) {335 this.stageParameters_ = default_stage_parameters;336 this.stageParameters_.bounds = this.bounds_;337 }338 this.stageParameters_.standingTransform = new gfx.mojom.Transform();339 this.stageParameters_.standingTransform.matrix =340 getMatrixFromTransform(floorOrigin);341 this.onStageParametersUpdated();342 }343 clearFloorOrigin() {344 if (this.stageParameters_) {345 this.stageParameters_ = null;346 this.onStageParametersUpdated();347 }348 }349 onStageParametersUpdated() {350 // Indicate for the frame loop that the stage parameters have been updated.351 this.stageParametersUpdated_ = true;352 this.displayInfo_.stageParameters = this.stageParameters_;353 if (this.sessionClient_.ptr.isBound()) {354 this.sessionClient_.onChanged(this.displayInfo_);355 }356 }357 simulateResetPose() {358 this.send_mojo_space_reset_ = true;359 }360 simulateInputSourceConnection(fakeInputSourceInit) {361 const index = this.next_input_source_index_;362 this.next_input_source_index_++;363 const source = new MockXRInputSource(fakeInputSourceInit, index, this);364 this.input_sources_.set(index, source);365 return source;366 }367 // Helper methods368 getNonImmersiveDisplayInfo() {369 const displayInfo = this.getImmersiveDisplayInfo();370 displayInfo.capabilities.canPresent = false;371 displayInfo.leftEye = null;372 displayInfo.rightEye = null;373 return displayInfo;374 }375 // Function to generate some valid display information for the device.376 getImmersiveDisplayInfo() {377 return {378 displayName: 'FakeDevice',379 capabilities: {380 hasPosition: false,381 hasExternalDisplay: false,382 canPresent: true,383 maxLayers: 1384 },385 stageParameters: null,386 leftEye: {387 fieldOfView: {388 upDegrees: 48.316,389 downDegrees: 50.099,390 leftDegrees: 50.899,391 rightDegrees: 35.197392 },393 headFromEye: composeGFXTransform({394 position: [-0.032, 0, 0],395 orientation: [0, 0, 0, 1]396 }),397 renderWidth: 20,398 renderHeight: 20399 },400 rightEye: {401 fieldOfView: {402 upDegrees: 48.316,403 downDegrees: 50.099,404 leftDegrees: 50.899,405 rightDegrees: 35.197406 },407 headFromEye: composeGFXTransform({408 position: [0.032, 0, 0],409 orientation: [0, 0, 0, 1]410 }),411 renderWidth: 20,412 renderHeight: 20413 },414 webxrDefaultFramebufferScale: 0.7,415 };416 }417 // This function converts between the matrix provided by the WebXR test API418 // and the internal data representation.419 getEye(fakeXRViewInit) {420 let fov = null;421 if (fakeXRViewInit.fieldOfView) {422 fov = {423 upDegrees: fakeXRViewInit.fieldOfView.upDegrees,424 downDegrees: fakeXRViewInit.fieldOfView.downDegrees,425 leftDegrees: fakeXRViewInit.fieldOfView.leftDegrees,426 rightDegrees: fakeXRViewInit.fieldOfView.rightDegrees427 };428 } else {429 const m = fakeXRViewInit.projectionMatrix;430 function toDegrees(tan) {431 return Math.atan(tan) * 180 / Math.PI;432 }433 const leftTan = (1 - m[8]) / m[0];434 const rightTan = (1 + m[8]) / m[0];435 const upTan = (1 + m[9]) / m[5];436 const downTan = (1 - m[9]) / m[5];437 fov = {438 upDegrees: toDegrees(upTan),439 downDegrees: toDegrees(downTan),440 leftDegrees: toDegrees(leftTan),441 rightDegrees: toDegrees(rightTan)442 };443 }444 return {445 fieldOfView: fov,446 headFromEye: composeGFXTransform(fakeXRViewInit.viewOffset),447 renderWidth: fakeXRViewInit.resolution.width,448 renderHeight: fakeXRViewInit.resolution.height449 };450 }451 setFeatures(supportedFeatures) {452 function convertFeatureToMojom(feature) {453 if (feature in MockRuntime.featureToMojoMap) {454 return MockRuntime.featureToMojoMap[feature];455 } else {456 return device.mojom.XRSessionFeature.INVALID;457 }458 }459 this.supportedFeatures_ = [];460 for (let i = 0; i < supportedFeatures.length; i++) {461 const feature = convertFeatureToMojom(supportedFeatures[i]);462 if (feature !== device.mojom.XRSessionFeature.INVALID) {463 this.supportedFeatures_.push(feature);464 }465 }466 }467 // These methods are intended to be used by MockXRInputSource only.468 addInputSource(source) {469 if (!this.input_sources_.has(source.source_id_)) {470 this.input_sources_.set(source.source_id_, source);471 }472 }473 removeInputSource(source) {474 this.input_sources_.delete(source.source_id_);475 }476 // Extension point for non-standard modules.477 _injectAdditionalFrameData(options, frameData) {478 }479 // Mojo function implementations.480 // XRFrameDataProvider implementation.481 getFrameData(options) {482 const mojo_space_reset = this.send_mojo_space_reset_;483 this.send_mojo_space_reset_ = false;484 const stage_parameters_updated = this.stageParametersUpdated_;485 this.stageParametersUpdated_ = false;486 if (this.pose_) {487 this.pose_.poseIndex++;488 }489 // Setting the input_state to null tests a slightly different path than490 // the browser tests where if the last input source is removed, the device491 // code always sends up an empty array, but it's also valid mojom to send492 // up a null array.493 let input_state = null;494 if (this.input_sources_.size > 0) {495 input_state = [];496 for (const input_source of this.input_sources_.values()) {497 input_state.push(input_source.getInputSourceState());498 }499 }500 // Convert current document time to monotonic time.501 let now = window.performance.now() / 1000.0;502 const diff = now - internals.monotonicTimeToZeroBasedDocumentTime(now);503 now += diff;504 now *= 1000000;505 const frameData = {506 pose: this.pose_,507 mojoSpaceReset: mojo_space_reset,508 inputState: input_state,509 timeDelta: {510 microseconds: now,511 },512 frameId: this.next_frame_id_++,513 bufferHolder: null,514 bufferSize: {},515 stageParameters: this.stageParameters_,516 stageParametersUpdated: stage_parameters_updated,517 };518 this._calculateHitTestResults(frameData);519 this._injectAdditionalFrameData(options, frameData);520 return Promise.resolve({521 frameData: frameData,522 });523 }524 getEnvironmentIntegrationProvider(environmentProviderRequest) {525 this.environmentProviderBinding_ = new mojo.AssociatedBinding(526 device.mojom.XREnvironmentIntegrationProvider, this,527 environmentProviderRequest);528 }529 // Note that if getEnvironmentProvider hasn't finished running yet this will530 // be undefined. It's recommended that you allow a successful task to post531 // first before attempting to close.532 closeEnvironmentIntegrationProvider() {533 this.environmentProviderBinding_.close();534 }535 closeDataProvider() {536 this.dataProviderBinding_.close();537 }538 updateSessionGeometry(frame_size, display_rotation) {539 // This function must exist to ensure that calls to it do not crash, but we540 // do not have any use for this data at present.541 }542 // XREnvironmentIntegrationProvider implementation:543 subscribeToHitTest(nativeOriginInformation, entityTypes, ray) {544 if (!this.supportedModes_.includes(device.mojom.XRSessionMode.kImmersiveAr)) {545 // Reject outside of AR.546 return Promise.resolve({547 result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,548 subscriptionId : 0549 });550 }551 if (nativeOriginInformation.$tag == device.mojom.XRNativeOriginInformation.Tags.inputSourceId) {552 if (!this.input_sources_.has(nativeOriginInformation.inputSourceId)) {553 // Reject - unknown input source ID.554 return Promise.resolve({555 result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,556 subscriptionId : 0557 });558 }559 } else if (nativeOriginInformation.$tag == device.mojom.XRNativeOriginInformation.Tags.referenceSpaceCategory) {560 // Bounded_floor & unbounded ref spaces are not yet supported for AR:561 if (nativeOriginInformation.referenceSpaceCategory == device.mojom.XRReferenceSpaceCategory.UNBOUNDED562 || nativeOriginInformation.referenceSpaceCategory == device.mojom.XRReferenceSpaceCategory.BOUNDED_FLOOR) {563 return Promise.resolve({564 result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,565 subscriptionId : 0566 });567 }568 } else {569 // Planes and anchors are not yet supported by the mock interface.570 return Promise.resolve({571 result : device.mojom.SubscribeToHitTestResult.FAILURE_GENERIC,572 subscriptionId : 0573 });574 }575 // Store the subscription information as-is:576 const id = this.next_hit_test_id_++;577 this.hitTestSubscriptions_.set(id, { nativeOriginInformation, entityTypes, ray });578 return Promise.resolve({579 result : device.mojom.SubscribeToHitTestResult.SUCCESS,580 subscriptionId : id581 });582 }583 // Utility function584 requestRuntimeSession(sessionOptions) {585 return this.runtimeSupportsSession(sessionOptions).then((result) => {586 // The JavaScript bindings convert c_style_names to camelCase names.587 const options = new device.mojom.XRPresentationTransportOptions();588 options.transportMethod =589 device.mojom.XRPresentationTransportMethod.SUBMIT_AS_MAILBOX_HOLDER;590 options.waitForTransferNotification = true;591 options.waitForRenderNotification = true;592 let submit_frame_sink;593 if (result.supportsSession) {594 submit_frame_sink = {595 clientReceiver: this.presentation_provider_.getClientReceiver(),596 provider: this.presentation_provider_.bindProvider(sessionOptions),597 transportOptions: options598 };599 const dataProviderPtr = new device.mojom.XRFrameDataProviderPtr();600 const dataProviderRequest = mojo.makeRequest(dataProviderPtr);601 this.dataProviderBinding_ = new mojo.Binding(602 device.mojom.XRFrameDataProvider, this, dataProviderRequest);603 const clientReceiver = mojo.makeRequest(this.sessionClient_);604 const enabled_features = [];605 for (let i = 0; i < sessionOptions.requiredFeatures.length; i++) {606 if (this.supportedFeatures_.indexOf(sessionOptions.requiredFeatures[i]) !== -1) {607 enabled_features.push(sessionOptions.requiredFeatures[i]);608 } else {609 return Promise.resolve({session: null});610 }611 }612 for (let i =0; i < sessionOptions.optionalFeatures.length; i++) {613 if (this.supportedFeatures_.indexOf(sessionOptions.optionalFeatures[i]) !== -1) {614 enabled_features.push(sessionOptions.optionalFeatures[i]);615 }616 }617 return Promise.resolve({618 session: {619 submitFrameSink: submit_frame_sink,620 dataProvider: dataProviderPtr,621 clientReceiver: clientReceiver,622 displayInfo: this.displayInfo_,623 enabledFeatures: enabled_features,624 }625 });626 } else {627 return Promise.resolve({session: null});628 }629 });630 }631 runtimeSupportsSession(options) {632 return Promise.resolve({633 supportsSession: this.supportedModes_.includes(options.mode)634 });635 }636 // Private functions - hit test implementation:637 // Modifies passed in frameData to add hit test results.638 _calculateHitTestResults(frameData) {639 if (!this.supportedModes_.includes(device.mojom.XRSessionMode.kImmersiveAr)) {640 return;641 }642 frameData.hitTestSubscriptionResults = new device.mojom.XRHitTestSubscriptionResultsData();643 frameData.hitTestSubscriptionResults.results = [];644 frameData.hitTestSubscriptionResults.transientInputResults = [];645 if (!this.world_) {646 return;647 }648 // Non-transient hit test:649 for (const [id, subscription] of this.hitTestSubscriptions_) {650 const mojo_from_native_origin = this._getMojoFromNativeOrigin(subscription.nativeOriginInformation);651 if (!mojo_from_native_origin) continue;652 const ray_origin = {x: subscription.ray.origin.x, y: subscription.ray.origin.y, z: subscription.ray.origin.z, w: 1};653 const ray_direction = {x: subscription.ray.direction.x, y: subscription.ray.direction.y, z: subscription.ray.direction.z, w: 0};654 const mojo_ray_origin = XRMathHelper.transform_by_matrix(mojo_from_native_origin, ray_origin);655 const mojo_ray_direction = XRMathHelper.transform_by_matrix(mojo_from_native_origin, ray_direction);656 const results = this._hitTestWorld(mojo_ray_origin, mojo_ray_direction, subscription.entityTypes);657 const result = new device.mojom.XRHitTestSubscriptionResultData();658 result.subscriptionId = id;659 result.hitTestResults = results;660 frameData.hitTestSubscriptionResults.results.push(result);661 }662 }663 // Hit tests the passed in ray (expressed as origin and direction) against the mocked world data.664 _hitTestWorld(origin, direction, entityTypes) {665 let result = [];666 for (const region of this.world_.hitTestRegions) {667 const partial_result = this._hitTestRegion(668 region,669 origin, direction,670 entityTypes);671 result = result.concat(partial_result);672 }673 return result.sort((lhs, rhs) => lhs.distance - rhs.distance);674 }675 // Hit tests the passed in ray (expressed as origin and direction) against world region.676 // |entityTypes| is a set of FakeXRRegionTypes.677 // |region| is FakeXRRegion.678 // Returns array of XRHitResults, each entry will be decorated with the distance from the ray origin (along the ray).679 _hitTestRegion(region, origin, direction, entityTypes) {680 const regionNameToMojoEnum = {681 "point":device.mojom.EntityTypeForHitTest.POINT,682 "plane":device.mojom.EntityTypeForHitTest.PLANE,683 "mesh":null684 };685 if (!entityTypes.includes(regionNameToMojoEnum[region.type])) {686 return [];687 }688 const result = [];689 for (const face of region.faces) {690 const maybe_hit = this._hitTestFace(face, origin, direction);691 if (maybe_hit) {692 result.push(maybe_hit);693 }694 }695 // The results should be sorted by distance and there should be no 2 entries with696 // the same distance from ray origin - that would mean they are the same point.697 // This situation is possible when a ray intersects the region through an edge shared698 // by 2 faces.699 return result.sort((lhs, rhs) => lhs.distance - rhs.distance)700 .filter((val, index, array) => index === 0 || val.distance !== array[index - 1].distance);701 }702 // Hit tests the passed in ray (expressed as origin and direction) against a single face.703 // |face|, |origin|, and |direction| are specified in world (aka mojo) coordinates.704 // |face| is an array of DOMPointInits.705 // Returns null if the face does not intersect with the ray, otherwise the result is706 // an XRHitResult with matrix describing the pose of the intersection point.707 _hitTestFace(face, origin, direction) {708 const add = XRMathHelper.add;709 const sub = XRMathHelper.sub;710 const mul = XRMathHelper.mul;711 const normalize = XRMathHelper.normalize;712 const dot = XRMathHelper.dot;713 const cross = XRMathHelper.cross;714 const neg = XRMathHelper.neg;715 //1. Calculate plane normal in world coordinates.716 const point_A = face[0];717 const point_B = face[1];718 const point_C = face[2];719 const edge_AB = sub(point_B, point_A);720 const edge_AC = sub(point_C, point_A);721 const normal = normalize(cross(edge_AB, edge_AC));722 const numerator = dot(sub(point_A, origin), normal);723 const denominator = dot(direction, normal);724 if (Math.abs(denominator) < 0.0001) {725 // Planes are nearly parallel - there's either infinitely many intersection points or 0.726 // Both cases signify a "no hit" for us.727 return null;728 } else {729 // Single intersection point between the infinite plane and the line (*not* ray).730 // Need to calculate the hit test matrix taking into account the face vertices.731 const distance = numerator / denominator;732 if (distance < 0) {733 // Line - plane intersection exists, but not the half-line - plane does not.734 return null;735 } else {736 const intersection_point = add(origin, mul(distance, direction));737 // Since we are treating the face as a solid, flip the normal so that its738 // half-space will contain the ray origin.739 const y_axis = denominator > 0 ? neg(normal) : normal;740 let z_axis = null;741 const cos_direction_and_y_axis = dot(direction, y_axis);742 if (Math.abs(cos_direction_and_y_axis) > 0.9999) {743 // Ray and the hit test normal are co-linear - try using the 'up' or 'right' vector's projection on the face plane as the Z axis.744 // Note: this edge case is currently not covered by the spec.745 const up = {x: 0.0, y: 1.0, z: 0.0, w: 0.0};746 const right = {x:1.0, y: 0.0, z: 0.0, w: 0.0};747 z_axis = Math.abs(dot(up, y_axis)) > 0.9999748 ? sub(up, mul(dot(right, y_axis), y_axis)) // `up is also co-linear with hit test normal, use `right`749 : sub(up, mul(dot(up, y_axis), y_axis)); // `up` is not co-linear with hit test normal, use it750 } else {751 // Project the ray direction onto the plane, negate it and use as a Z axis.752 z_axis = neg(sub(direction, mul(cos_direction_and_y_axis, y_axis))); // Z should point towards the ray origin, not away.753 }754 const x_axis = normalize(cross(y_axis, z_axis));755 // Filter out the points not in polygon.756 if (!XRMathHelper.pointInFace(intersection_point, face)) {757 return null;758 }759 const hitResult = new device.mojom.XRHitResult();760 hitResult.hitMatrix = new gfx.mojom.Transform();761 hitResult.distance = distance; // Extend the object with additional information used by higher layers.762 // It will not be serialized over mojom.763 hitResult.hitMatrix.matrix = new Array(16);764 hitResult.hitMatrix.matrix[0] = x_axis.x;765 hitResult.hitMatrix.matrix[1] = x_axis.y;766 hitResult.hitMatrix.matrix[2] = x_axis.z;767 hitResult.hitMatrix.matrix[3] = 0;768 hitResult.hitMatrix.matrix[4] = y_axis.x;769 hitResult.hitMatrix.matrix[5] = y_axis.y;770 hitResult.hitMatrix.matrix[6] = y_axis.z;771 hitResult.hitMatrix.matrix[7] = 0;772 hitResult.hitMatrix.matrix[8] = z_axis.x;773 hitResult.hitMatrix.matrix[9] = z_axis.y;774 hitResult.hitMatrix.matrix[10] = z_axis.z;775 hitResult.hitMatrix.matrix[11] = 0;776 hitResult.hitMatrix.matrix[12] = intersection_point.x;777 hitResult.hitMatrix.matrix[13] = intersection_point.y;778 hitResult.hitMatrix.matrix[14] = intersection_point.z;779 hitResult.hitMatrix.matrix[15] = 1;780 return hitResult;781 }782 }783 }784 _getMojoFromNativeOrigin(nativeOriginInformation) {785 const identity = function() {786 return [787 1, 0, 0, 0,788 0, 1, 0, 0,789 0, 0, 1, 0,790 0, 0, 0, 1791 ];792 };793 if (nativeOriginInformation.$tag == device.mojom.XRNativeOriginInformation.Tags.inputSourceId) {794 if (!this.input_sources_.has(nativeOriginInformation.inputSourceId)) {795 return null;796 } else {797 const inputSource = this.input_sources_.get(nativeOriginInformation.inputSourceId);798 return inputSource.mojo_from_input_.matrix;799 }800 } else if (nativeOriginInformation.$tag == device.mojom.XRNativeOriginInformation.Tags.referenceSpaceCategory) {801 switch (nativeOriginInformation.referenceSpaceCategory) {802 case device.mojom.XRReferenceSpaceCategory.LOCAL:803 return identity();804 case device.mojom.XRReferenceSpaceCategory.LOCAL_FLOOR:805 if (this.stageParameters_ == null || this.stageParameters_.standingTransform == null) {806 console.warn("Standing transform not available.");807 return null;808 }809 // this.stageParameters_.standingTransform = floor_from_mojo aka native_origin_from_mojo810 return XRMathHelper.inverse(this.stageParameters_.standingTransform.matrix);811 case device.mojom.XRReferenceSpaceCategory.VIEWER:812 const transform = {813 position: [814 this.pose_.position.x,815 this.pose_.position.y,816 this.pose_.position.z],817 orientation: [818 this.pose_.orientation.x,819 this.pose_.orientation.y,820 this.pose_.orientation.z,821 this.pose_.orientation.w],822 };823 return getMatrixFromTransform(transform); // this.pose_ = mojo_from_viewer824 case device.mojom.XRReferenceSpaceCategory.BOUNDED_FLOOR:825 return null;826 case device.mojom.XRReferenceSpaceCategory.UNBOUNDED:827 return null;828 default:829 throw new TypeError("Unrecognized XRReferenceSpaceCategory!");830 }831 } else {832 // Anchors & planes are not yet supported for hit test.833 return null;834 }835 }836}837class MockXRSessionMetricsRecorder {838 reportFeatureUsed(feature) {839 // Do nothing840 }841}842class MockXRInputSource {843 constructor(fakeInputSourceInit, id, pairedDevice) {844 this.source_id_ = id;845 this.pairedDevice_ = pairedDevice;846 this.handedness_ = fakeInputSourceInit.handedness;847 this.target_ray_mode_ = fakeInputSourceInit.targetRayMode;848 this.setPointerOrigin(fakeInputSourceInit.pointerOrigin);849 this.setProfiles(fakeInputSourceInit.profiles);850 this.primary_input_pressed_ = false;851 if (fakeInputSourceInit.selectionStarted != null) {852 this.primary_input_pressed_ = fakeInputSourceInit.selectionStarted;853 }854 this.primary_input_clicked_ = false;855 if (fakeInputSourceInit.selectionClicked != null) {856 this.primary_input_clicked_ = fakeInputSourceInit.selectionClicked;857 }858 this.primary_squeeze_pressed_ = false;859 this.primary_squeeze_clicked_ = false;860 this.mojo_from_input_ = null;861 if (fakeInputSourceInit.gripOrigin != null) {862 this.setGripOrigin(fakeInputSourceInit.gripOrigin);863 }864 // This properly handles if supportedButtons were not specified.865 this.setSupportedButtons(fakeInputSourceInit.supportedButtons);866 this.emulated_position_ = false;867 this.desc_dirty_ = true;868 }869 // Webxr-test-api870 setHandedness(handedness) {871 if (this.handedness_ != handedness) {872 this.desc_dirty_ = true;873 this.handedness_ = handedness;874 }875 }876 setTargetRayMode(targetRayMode) {877 if (this.target_ray_mode_ != targetRayMode) {878 this.desc_dirty_ = true;879 this.target_ray_mode_ = targetRayMode;880 }881 }882 setProfiles(profiles) {883 this.desc_dirty_ = true;884 this.profiles_ = profiles;885 }886 setGripOrigin(transform, emulatedPosition = false) {887 // grip_origin was renamed to mojo_from_input in mojo888 this.mojo_from_input_ = new gfx.mojom.Transform();889 this.mojo_from_input_.matrix = getMatrixFromTransform(transform);890 this.emulated_position_ = emulatedPosition;891 }892 clearGripOrigin() {893 // grip_origin was renamed to mojo_from_input in mojo894 if (this.mojo_from_input_ != null) {895 this.mojo_from_input_ = null;896 this.emulated_position_ = false;897 }898 }899 setPointerOrigin(transform, emulatedPosition = false) {900 // pointer_origin was renamed to input_from_pointer in mojo901 this.desc_dirty_ = true;902 this.input_from_pointer_ = new gfx.mojom.Transform();903 this.input_from_pointer_.matrix = getMatrixFromTransform(transform);904 this.emulated_position_ = emulatedPosition;905 }906 disconnect() {907 this.pairedDevice_.removeInputSource(this);908 }909 reconnect() {910 this.pairedDevice_.addInputSource(this);911 }912 startSelection() {913 this.primary_input_pressed_ = true;914 if (this.gamepad_) {915 this.gamepad_.buttons[0].pressed = true;916 this.gamepad_.buttons[0].touched = true;917 }918 }919 endSelection() {920 if (!this.primary_input_pressed_) {921 throw new Error("Attempted to end selection which was not started");922 }923 this.primary_input_pressed_ = false;924 this.primary_input_clicked_ = true;925 if (this.gamepad_) {926 this.gamepad_.buttons[0].pressed = false;927 this.gamepad_.buttons[0].touched = false;928 }929 }930 simulateSelect() {931 this.primary_input_clicked_ = true;932 }933 setSupportedButtons(supportedButtons) {934 this.gamepad_ = null;935 this.supported_buttons_ = [];936 // If there are no supported buttons, we can stop now.937 if (supportedButtons == null || supportedButtons.length < 1) {938 return;939 }940 const supported_button_map = {};941 this.gamepad_ = this.getEmptyGamepad();942 for (let i = 0; i < supportedButtons.length; i++) {943 const buttonType = supportedButtons[i].buttonType;944 this.supported_buttons_.push(buttonType);945 supported_button_map[buttonType] = supportedButtons[i];946 }947 // Let's start by building the button state in order of priority:948 // Primary button is index 0.949 this.gamepad_.buttons.push({950 pressed: this.primary_input_pressed_,951 touched: this.primary_input_pressed_,952 value: this.primary_input_pressed_ ? 1.0 : 0.0953 });954 // Now add the rest of our buttons955 this.addGamepadButton(supported_button_map['grip']);956 this.addGamepadButton(supported_button_map['touchpad']);957 this.addGamepadButton(supported_button_map['thumbstick']);958 this.addGamepadButton(supported_button_map['optional-button']);959 this.addGamepadButton(supported_button_map['optional-thumbstick']);960 // Finally, back-fill placeholder buttons/axes961 for (let i = 0; i < this.gamepad_.buttons.length; i++) {962 if (this.gamepad_.buttons[i] == null) {963 this.gamepad_.buttons[i] = {964 pressed: false,965 touched: false,966 value: 0967 };968 }969 }970 for (let i=0; i < this.gamepad_.axes.length; i++) {971 if (this.gamepad_.axes[i] == null) {972 this.gamepad_.axes[i] = 0;973 }974 }975 }976 updateButtonState(buttonState) {977 if (this.supported_buttons_.indexOf(buttonState.buttonType) == -1) {978 throw new Error("Tried to update state on an unsupported button");979 }980 const buttonIndex = this.getButtonIndex(buttonState.buttonType);981 const axesStartIndex = this.getAxesStartIndex(buttonState.buttonType);982 if (buttonIndex == -1) {983 throw new Error("Unknown Button Type!");984 }985 // is this a 'squeeze' button?986 if (buttonIndex === this.getButtonIndex('grip')) {987 // squeeze988 if (buttonState.pressed) {989 this.primary_squeeze_pressed_ = true;990 } else if (this.gamepad_.buttons[buttonIndex].pressed) {991 this.primary_squeeze_clicked_ = true;992 this.primary_squeeze_pressed_ = false;993 } else {994 this.primary_squeeze_clicked_ = false;995 this.primary_squeeze_pressed_ = false;996 }997 }998 this.gamepad_.buttons[buttonIndex].pressed = buttonState.pressed;999 this.gamepad_.buttons[buttonIndex].touched = buttonState.touched;1000 this.gamepad_.buttons[buttonIndex].value = buttonState.pressedValue;1001 if (axesStartIndex != -1) {1002 this.gamepad_.axes[axesStartIndex] = buttonState.xValue == null ? 0.0 : buttonState.xValue;1003 this.gamepad_.axes[axesStartIndex + 1] = buttonState.yValue == null ? 0.0 : buttonState.yValue;1004 }1005 }1006 // Helpers for Mojom1007 getInputSourceState() {1008 const input_state = new device.mojom.XRInputSourceState();1009 input_state.sourceId = this.source_id_;1010 input_state.primaryInputPressed = this.primary_input_pressed_;1011 input_state.primaryInputClicked = this.primary_input_clicked_;1012 input_state.primarySqueezePressed = this.primary_squeeze_pressed_;1013 input_state.primarySqueezeClicked = this.primary_squeeze_clicked_;1014 // Setting the input source's "clicked" state should generate one "select"1015 // event. Reset the input value to prevent it from continuously generating1016 // events.1017 this.primary_input_clicked_ = false;1018 // Setting the input source's "clicked" state should generate one "squeeze"1019 // event. Reset the input value to prevent it from continuously generating1020 // events.1021 this.primary_squeeze_clicked_ = false;1022 input_state.mojoFromInput = this.mojo_from_input_;1023 input_state.gamepad = this.gamepad_;1024 input_state.emulatedPosition = this.emulated_position_;1025 if (this.desc_dirty_) {1026 const input_desc = new device.mojom.XRInputSourceDescription();1027 switch (this.target_ray_mode_) {1028 case 'gaze':1029 input_desc.targetRayMode = device.mojom.XRTargetRayMode.GAZING;1030 break;1031 case 'tracked-pointer':1032 input_desc.targetRayMode = device.mojom.XRTargetRayMode.POINTING;1033 break;1034 case 'screen':1035 input_desc.targetRayMode = device.mojom.XRTargetRayMode.TAPPING;1036 break;1037 default:1038 throw new Error('Unhandled target ray mode ' + this.target_ray_mode_);1039 }1040 switch (this.handedness_) {1041 case 'left':1042 input_desc.handedness = device.mojom.XRHandedness.LEFT;1043 break;1044 case 'right':1045 input_desc.handedness = device.mojom.XRHandedness.RIGHT;1046 break;1047 default:1048 input_desc.handedness = device.mojom.XRHandedness.NONE;1049 break;1050 }1051 input_desc.inputFromPointer = this.input_from_pointer_;1052 input_desc.profiles = this.profiles_;1053 input_state.description = input_desc;1054 this.desc_dirty_ = false;1055 }1056 // Pointer data for DOM Overlay, set by setOverlayPointerPosition()1057 if (this.overlay_pointer_position_) {1058 input_state.overlayPointerPosition = this.overlay_pointer_position_;1059 this.overlay_pointer_position_ = null;1060 }1061 return input_state;1062 }1063 setOverlayPointerPosition(x, y) {1064 this.overlay_pointer_position_ = {x: x, y: y};1065 }1066 getEmptyGamepad() {1067 // Mojo complains if some of the properties on Gamepad are null, so set1068 // everything to reasonable defaults that tests can override.1069 const gamepad = {1070 connected: true,1071 id: "",1072 timestamp: 0,1073 axes: [],1074 buttons: [],1075 mapping: "xr-standard",1076 display_id: 0,1077 };1078 switch (this.handedness_) {1079 case 'left':1080 gamepad.hand = device.mojom.GamepadHand.GamepadHandLeft;1081 break;1082 case 'right':1083 gamepad.hand = device.mojom.GamepadHand.GamepadHandRight;1084 break;1085 default:1086 gamepad.hand = device.mojom.GamepadHand.GamepadHandNone;1087 break;1088 }1089 return gamepad;1090 }1091 addGamepadButton(buttonState) {1092 if (buttonState == null) {1093 return;1094 }1095 const buttonIndex = this.getButtonIndex(buttonState.buttonType);1096 const axesStartIndex = this.getAxesStartIndex(buttonState.buttonType);1097 if (buttonIndex == -1) {1098 throw new Error("Unknown Button Type!");1099 }1100 this.gamepad_.buttons[buttonIndex] = {1101 pressed: buttonState.pressed,1102 touched: buttonState.touched,1103 value: buttonState.pressedValue1104 };1105 // Add x/y value if supported.1106 if (axesStartIndex != -1) {1107 this.gamepad_.axes[axesStartIndex] = (buttonState.xValue == null ? 0.0 : buttonSate.xValue);1108 this.gamepad_.axes[axesStartIndex + 1] = (buttonState.yValue == null ? 0.0 : buttonSate.yValue);1109 }1110 }1111 // General Helper methods1112 getButtonIndex(buttonType) {1113 switch (buttonType) {1114 case 'grip':1115 return 1;1116 case 'touchpad':1117 return 2;1118 case 'thumbstick':1119 return 3;1120 case 'optional-button':1121 return 4;1122 case 'optional-thumbstick':1123 return 5;1124 default:1125 return -1;1126 }1127 }1128 getAxesStartIndex(buttonType) {1129 switch (buttonType) {1130 case 'touchpad':1131 return 0;1132 case 'thumbstick':1133 return 2;1134 case 'optional-thumbstick':1135 return 4;1136 default:1137 return -1;1138 }1139 }1140}1141// Mojo helper classes1142class MockXRPresentationProvider {1143 constructor() {1144 this.binding_ = new mojo.Binding(device.mojom.XRPresentationProvider, this);1145 this.submit_frame_count_ = 0;1146 this.missing_frame_count_ = 0;1147 }1148 bindProvider(request) {1149 const providerPtr = new device.mojom.XRPresentationProviderPtr();1150 const providerRequest = mojo.makeRequest(providerPtr);1151 this.binding_.close();1152 this.binding_ = new mojo.Binding(1153 device.mojom.XRPresentationProvider, this, providerRequest);1154 return providerPtr;1155 }1156 getClientReceiver() {1157 this.submitFrameClient_ = new device.mojom.XRPresentationClientPtr();1158 return mojo.makeRequest(this.submitFrameClient_);1159 }1160 // XRPresentationProvider mojo implementation1161 submitFrameMissing(frameId, mailboxHolder, timeWaited) {1162 this.missing_frame_count_++;1163 }1164 submitFrame(frameId, mailboxHolder, timeWaited) {1165 this.submit_frame_count_++;1166 // Trigger the submit completion callbacks here. WARNING: The1167 // Javascript-based mojo mocks are *not* re-entrant. It's OK to1168 // wait for these notifications on the next frame, but waiting1169 // within the current frame would never finish since the incoming1170 // calls would be queued until the current execution context finishes.1171 this.submitFrameClient_.onSubmitFrameTransferred(true);1172 this.submitFrameClient_.onSubmitFrameRendered();1173 }1174 // Utility methods1175 Close() {1176 this.binding_.close();1177 }1178}1179// This is a temporary workaround for the fact that spinning up webxr before1180// the mojo interceptors are created will cause the interceptors to not get1181// registered, so we have to create this before we query xr;1182const XRTest = new ChromeXRTest();1183// This test API is also used to run Chrome's internal legacy VR tests; however,1184// those fail if navigator.xr has been used. Those tests will set a bool telling1185// us not to try to check navigator.xr1186if ((typeof legacy_vr_test === 'undefined') || !legacy_vr_test) {1187 // Some tests may run in the http context where navigator.xr isn't exposed1188 // This should just be to test that it isn't exposed, but don't try to set up1189 // the test framework in this case.1190 if (navigator.xr) {1191 navigator.xr.test = XRTest;1192 }1193} else {1194 navigator.vr = { test: XRTest };...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('wpt')2var angle = cos_direction_and_y_axis(0, 0, 5, 5)3console.log(angle)4var wpt = require('wpt')5var angle = cos_direction_and_y_axis(0, 0, 5, 5)6console.log(angle)7var wpt = require('wpt')8var angle = cos_direction_and_y_axis(0, 0, 5, 5)9console.log(angle)10var wpt = require('wpt')11var angle = cos_direction_and_y_axis(0, 0, 5, 5)12console.log(angle)13var wpt = require('wpt')14var angle = cos_direction_and_y_axis(0, 0, 5, 5)15console.log(angle)16var wpt = require('wpt')17var angle = cos_direction_and_y_axis(0, 0, 5, 5)18console.log(angle)19var wpt = require('wpt')20var angle = cos_direction_and_y_axis(0, 0, 5, 5)21console.log(angle)22var wpt = require('wpt')

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('wpt');2wpt.cos_direction_and_y_axis(0, 0, 1, 0, 1, 0);3var wpt = require('wpt');4wpt.cos_direction_and_y_axis(0, 0, 1, 0, .5, 0);5var wpt = require('wpt');6wpt.cos_direction_and_y_axis(0, 0, 1, 0, 0, 0);7var wpt = require('wpt');8wpt.cos_direction_and_y_axis(0, 0, 1, 0, -1, 0);9var wpt = require('wpt');10wpt.cos_direction_and_y_axis(0, 0, 1, 0, -1, -1);11var wpt = require('wpt');12wpt.cos_direction_and_y_axis(0, 0, 1, 0, 0, -1);13var wpt = require('wpt');14wpt.cos_direction_and_y_axis(0, 0, 1, 0, 1, -1);15var wpt = require('wpt');16wpt.cos_direction_and_y_axis(0, 0, 1, 0, 1, 1);

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('./wpt.js');2var mywpt = new wpt(0,0,0,0,0,0);3console.log(mywpt.cos_direction_and_y_axis(1,1,1,1,1,1));4var wpt = function(x,y,z,hdg,pitch,roll) {5 this.x = x;6 this.y = y;7 this.z = z;8 this.hdg = hdg;9 this.pitch = pitch;10 this.roll = roll;11};12wpt.prototype.cos_direction_and_y_axis = function(x, y, z, hdg, pitch, roll) {13 var dx = x - this.x;14 var dy = y - this.y;15 var dz = z - this.z;16 var d = Math.sqrt(dx * dx + dy * dy + dz * dz);17 var cos = (dx * Math.sin(hdg) - dy * Math.cos(hdg)) / d;18 return cos;19};20module.exports = wpt;21var wpt = function(x,y,z,hdg,pitch,roll) {22 this.x = x;23 this.y = y;24 this.z = z;25 this.hdg = hdg;26 this.pitch = pitch;27 this.roll = roll;28};

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('wpt.js');2var cos = wpt.cos_direction_and_y_axis(0,0,1,0,0,1,1,0,0);3console.log(cos);4cos_direction_and_y_axis: function(x1,y1,z1,x2,y2,z2,x3,y3,z3){5 var v1 = [x2-x1,y2-y1,z2-z1];6 var v2 = [x3-x1,y3-y1,z3-z1];7 var v1_length = Math.sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]);8 var v2_length = Math.sqrt(v2[0]*v2[0]+v2[1]*v2[1]+v2[2]*v2[2]);9 var cos = (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2])/(v1_length*v2_length);10 return cos;11},12var wpt = require('./wpt.js');13var cos = wpt.cos_direction_and_y_axis(0,0,1,0,0,1,1,0,0);14console.log(cos);15exports.cos_direction_and_y_axis = function(x1,y1,z1,x2,y2,z2,x3,y3,z3){16 var v1 = [x2-x1,y2-y1,z2-z1];17 var v2 = [x3-x1,y3-y1,z3-z1];18 var v1_length = Math.sqrt(v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]);19 var v2_length = Math.sqrt(v2[0]*v2[0]+v2[1]*v2[1]+v2[2]*v2[2]);20 var cos = (v1[0]*v2[0]+v1[1]*v2[1]+

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('wpt.js');2var wpt = new wpt();3var lat1 = 0;4var lon1 = 0;5var lat2 = 0;6var lon2 = 0;7var y = 0;8var result = wpt.cos_direction_and_y_axis(lat1, lon1, lat2, lon2, y);9console.log(result);

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('wptools');2var wp = new wptools.page('Eiffel Tower');3wp.fetch(function(err, resp) {4 if (err) {5 console.log(err);6 } else {7 console.log(resp);8 }9});

Full Screen

Using AI Code Generation

copy

Full Screen

1var wpt = require('./wpt');2var cos = wpt.cos_direction_and_y_axis(0, 0, 1, 1);3console.log(cos);4var wpt = require('./wpt');5module.exports = {6 cos_direction_and_y_axis: function(x1, y1, x2, y2) {7 var dx = x2 - x1;8 var dy = y2 - y1;9 return dx / Math.sqrt(dx * dx + dy * dy);10 }11};12I am trying to get the cosine of the angle between the x-axis and the ray from (x1

Full Screen

Using AI Code Generation

copy

Full Screen

1var wptools = require('./wptools.js');2var y = wptools.cos_direction_and_y_axis(1,1,2,2);3console.log(y);4var wptools = {5 cos_direction_and_y_axis: function(x1, y1, x2, y2) {6 var dx = x2 - x1;7 var dy = y2 - y1;8 return dy / Math.sqrt(dx * dx + dy * dy);9 }10};11module.exports = wptools;12var wptools = require('./wptools.js');13var y = wptools.cos_direction_and_y_axis(1,1,2,2);14console.log(y);15var fs = require('fs');16var file = fs.readFileSync('test.txt', 'utf8');17fs.writeFileSync('test2.txt', file);18I am trying to use the require() function in Node.js to use the fs module. I am doing this in the following way:19var fs = require('fs');20var file = fs.readFileSync('test.txt', 'utf8');21fs.writeFileSync('test2.txt', file);22I think this is because I am using the require() function, but I do not

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run wpt automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful