Thursday, 24 November 2022

Better arrow cone rotation using ThreeJs

I'm drawing an arrow between pick and place points using QuadraticBezierCurve3 and ConeGeometry, but the rotation of the cone is not perfect as you can see in the snippet down!

Can you please tell me how can I improve the visualization (cone rotation) of my arrow function? thanks in advance.

var camera, scene, renderer;

init();
animate();

 /**
 draw arrow
*/
function drawArrow(pick_pos, place_pos, scene) {
    /**
    * Curve
    */
    const start = new THREE.Vector3();
    start.add(pick_pos)
    
    const finish = new THREE.Vector3();
    finish.add(place_pos)

    let mid = new THREE.Vector3();
    mid.add(start);
    let dist = finish.x + mid.x;
    mid.x = dist/2;
    mid.y += 3;

const b_curve = new THREE.QuadraticBezierCurve3(
    start,
    mid,
    finish
);
const points = b_curve.getPoints( 100 );
const line_geometry = new THREE.BufferGeometry().setFromPoints( points );
const material = new THREE.LineBasicMaterial( { color: 0x0ffffb, linewidth:5 } );
const curve = new THREE.Line( line_geometry, material );
/**
 * Cone
 */
const cone_geometry = new THREE.ConeGeometry( 0.2, 1, 8 );
const cone_material = new THREE.MeshBasicMaterial({ color: 0xff00fb });

const cone = new THREE.Mesh( cone_geometry, cone_material );
cone.position.set(points[98].x, points[98].y, points[98].z);
cone.rotateX(Math.PI * points[100].x); 
cone.rotateZ(Math.PI * points[100].z);

/**
 * Arrow
 */

const arrow = new THREE.Group();
arrow.add(curve);
arrow.add(cone);
arrow.name = 'arrow';
scene.add(arrow);
}

/**
 Create the scene, camera, renderer
*/
function init() {
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x21252d);
  renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.x = 0;
  camera.position.y = 8;
  camera.position.z = 10;
  scene.add(camera);
  
  controls = new THREE.OrbitControls(camera, renderer.domElement);
  
  const pick = new THREE.Vector3(0, 0, 0);
  const place = new THREE.Vector3(5, 0, 5);
  drawArrow(pick, place, scene);
  window.addEventListener('resize', onWindowResize);

}

function onWindowResize() {
 camera.aspect = window.innerWidth / window.innerHeight;
 camera.updateProjectionMatrix();
 renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  renderer.render(scene, camera);
}
<script src="https://cdn.jsdelivr.net/npm/three@0.122.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.122.0/examples/js/controls/OrbitControls.min.js"></script>


from Better arrow cone rotation using ThreeJs

FCM: Is data message delivery really less reliable than notification message delivery?

Question

I have come across some voices stating that FCM data message delivery is less consistent compared to that of notification messages. Does anyone have direct experience or can point me to resources exploring the issue? Or is a notification message just a collapsible, high-priority data message that the Firebase SDK handles automatically?

The question does not consider the case of force quitting the app. In this scenario, both types of messages will not be delivered (to my knowledge).

Background

I am writing a new Android SDK for a push service provider (similar to OneSignal). The SDK should handle the display of push notifications by default, optionally the client app can handle incoming pushes itself.

The actual delivery is of course done by Firebase Cloud Messaging (on devices running Play Services). So there are 2 types of messages to choose from on FCM: data vs notification messages.

As data messages are consistently handled by the registered FirebaseMessagingService (provided there is no notification key in the payload), this should be the way to go for the SDK. [See documentation] So far, I have not been able to produce a situation in which a data message was not delivered (foreground or background).



from FCM: Is data message delivery really less reliable than notification message delivery?

petite-vue mount and unmount events with nested v-if

I'm trying to understand why I'm getting multiple/extra mount and unmount events in petite-vue. I've seen similar questions with regard to Vue proper (and components), and I think they are in the same realm, but still a bit confused.

It seems that when I do get all the multiple mount events, there is only one event triggered where the element being mounted is has el.isConnected=true so I could maybe use that as a trigger as to whether or not to run the attached event handler, but I'm worried about performance as the number of events build and build while modifying the model state.

Is the a different way I should be writing these so I don't get multiple events ?

Scenarios :

  1. Click Edit, then Cancel: Why two unmounts for the v-for="item in model.beneficiaries" ?
  2. Click Edit, then Save: All OK. Click Accept: Why isConnected = false mount on 'Edit Screen' ?
  3. Repeat cycles of Edit, Cancel or Edit Save, then Accept and read notes about acceptClicks.

JSFiddle

<script type="module">
    import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'

    const state = reactive({
        setMode: function (benefit) {
            var beneficiaries = benefit == undefined ? [] : [ "Spouse", "Son" ];
            this.model.beneficiaries = beneficiaries;
            this.model.currentBenefit = benefit;
            this.model.showConfirm = false;
        },
        startEdit: function (benefit) {
            console.log("Edit Clicked");
            this.setMode(benefit);
        },
        cancelEdit: function () {
            console.log("Cancel Clicked");
            this.setMode();
        },
        saveBenefit: function () {
            console.log("Save Clicked");
            this.model.showConfirm = true;
        },
        acceptBenefit: function () {
            console.log("Accept Clicked");
            this.model.acceptClicks++;
            this.setMode();
        },
        model: {
            acceptClicks: 0,
            currentBenefit: undefined,
            showConfirm: false,
            beneficiaries: []
        }
    });

    createApp(state).mount('#app')
</script>

<div id="app" v-scope>
    <div>State:</div>
    <div>currentBenefit: </div>
    <div>showConfirm: </div>
    <div>beneficiaries: </div>
    <div>acceptClicks: </div>
    <div v-if="model.acceptClicks > 0">
        <div>After each Accept</div>
        <ul>
            <li>When clicking Edit,  isConnected=false mounts for 'Has Beneficiaries', 'Spouse' and 'Son'</li>
            <li>When clicking Edit, then Cancel, 2 unmounts for 'Spouse' and 'Son'; 1 unmounts for 'Has Beneficiaries'</li>
        </ul>
    </div>

    <div v-if="model.currentBenefit != undefined">
        <h3>Editing </h3>
        <div v-if="!model.showConfirm">
            <div @vue:mounted="console.log('Mount: ' + $el.innerHTML + ', isConnected: ' + $el.isConnected)" @vue:unmounted="console.log('Unmount: ' + $el.innerHTML)">Edit Screen</div>
            <div v-if="model.beneficiaries.length > 0">
                <div @vue:mounted="console.log('Mount: ' + $el.innerHTML + ', isConnected: ' + $el.isConnected)" @vue:unmounted="console.log('Unmount: ' + $el.innerHTML)">Has Beneficiaries</div>
                <div v-for="item in model.beneficiaries">
                    <div @vue:mounted="console.log('Mount: ' + $el.innerHTML + ', isConnected: ' + $el.isConnected)" @vue:unmounted="console.log('Unmount: ' + $el.innerHTML)"></div>
                </div>
            </div>

            <button type="button" @click.prevent="cancelEdit">Cancel</button>
            <button type="button" @click.prevent="saveBenefit">Save Benefit</button>
        </div>
        <div v-if="model.showConfirm">
            <button type="button" @click.prevent="acceptBenefit">Accept Confirm</button>
        </div>
    </div>
    <div v-if="model.currentBenefit == undefined">
        <h3>No Benefit</h3>
        <button type="button" @click.prevent="startEdit($event, { name: 'Health Benefit' })">Edit Benefit</button>
    </div>
</div>


from petite-vue mount and unmount events with nested v-if