diff --git a/src/components/ConcernementMapItem.vue b/src/components/ConcernementMapItem.vue index 9d1bd13..35e535c 100644 --- a/src/components/ConcernementMapItem.vue +++ b/src/components/ConcernementMapItem.vue @@ -369,7 +369,7 @@ export default { // INFO https://github.com/liabru/matter-attractors/issues/8 // INFO https://github.com/liabru/matter-attractors/blob/master/index.js // INFO https://github.com/liabru/matter-attractors/blob/master/build/matter-attractors.js#L180 - MatterAttractors.Attractors.gravityConstant = -20; + // MatterAttractors.Attractors.gravityConstant = -20; // Create parts of the body : main big circle & entities // INFO map a range of numbers to another range of numbers https://stackoverflow.com/a/46462321 @@ -378,8 +378,8 @@ export default { let ray = ray_range[0] + (this.entites.length - entite_range[0]) * (ray_range[1] - ray_range[0]) / (entite_range[1] - entite_range[0]); this.body_parts = [ Matter.Bodies.circle(0, 0, ray, { - item_type: 'concernement', - id: this.concernement.id, + // item_type: 'concernement', + // id: this.concernement.id, }) ]; @@ -400,37 +400,37 @@ export default { collisionFilter: { group: -1 }, - plugin: { - attractors: [ - // // there is a built in helper function for Newtonian gravity! - // // you can find out how it works in index.js - MatterAttractors.Attractors.gravity + // plugin: { + // attractors: [ + // // // there is a built in helper function for Newtonian gravity! + // // // you can find out how it works in index.js + // MatterAttractors.Attractors.gravity - // function(bodyA, bodyB) { - // var force = { - // x: (bodyA.position.x - bodyB.position.x) * 1e-6, - // y: (bodyA.position.y - bodyB.position.y) * 1e-6 - // } - // // apply force to both bodies - // Matter.Body.applyForce(bodyA, bodyA.position, force); - // Matter.Body.applyForce(bodyB, bodyB.position, Matter.Vector.neg(force)); - // } + // // function(bodyA, bodyB) { + // // var force = { + // // x: (bodyA.position.x - bodyB.position.x) * 1e-6, + // // y: (bodyA.position.y - bodyB.position.y) * 1e-6 + // // } + // // // apply force to both bodies + // // Matter.Body.applyForce(bodyA, bodyA.position, force); + // // Matter.Body.applyForce(bodyB, bodyB.position, Matter.Vector.neg(force)); + // // } - // INFO https://github.com/liabru/matter-attractors/blob/master/build/matter-attractors.js#L192 - // function (bodyA, bodyB){ - // // use Newton's law of gravitation - // var bToA = Matter.Vector.sub(bodyB.position, bodyA.position), - // distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001, - // normal = Matter.Vector.normalise(bToA), - // magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq), - // force = Matter.Vector.mult(normal, magnitude); + // // INFO https://github.com/liabru/matter-attractors/blob/master/build/matter-attractors.js#L192 + // // function (bodyA, bodyB){ + // // // use Newton's law of gravitation + // // var bToA = Matter.Vector.sub(bodyB.position, bodyA.position), + // // distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001, + // // normal = Matter.Vector.normalise(bToA), + // // magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq), + // // force = Matter.Vector.mult(normal, magnitude); - // // to apply forces to both bodies - // Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force)); - // Matter.Body.applyForce(bodyB, bodyB.position, force); - // } - ] - } + // // // to apply forces to both bodies + // // Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force)); + // // Matter.Body.applyForce(bodyB, bodyB.position, force); + // // } + // ] + // } }); Matter.Body.setPosition(this.body, this.pos); @@ -464,7 +464,7 @@ export default { this.paper_main_object.addChild(this.setPaperContour()); if (this.concernement.has_superpositions) { - this.paper_main_object.addChild(this.setPaperSuperpositions()); + this.paper_main_object.addChild(this.setPaperEntitesSuperposees()); } if (this.concernement.has_puissancedagir) { @@ -639,7 +639,7 @@ export default { } return g; }, - setPaperSuperpositions(){ + setPaperEntitesSuperposees(){ console.log('setPaperSuperpositions'); let g = new paper.Group({ pivot: new paper.Point(this.pos), @@ -1490,8 +1490,8 @@ export default { } // reset all matter rotation forces otherwise items will spin when colide - // Matter.Body.setAngle(this.body, 0); - // Matter.Body.setAngularSpeed(this.body, 0); + Matter.Body.setAngle(this.body, 0); + Matter.Body.setAngularSpeed(this.body, 0); }, applyFocusForces(){ if(!this.isFocused()) { @@ -1808,6 +1808,7 @@ export default { this.handlePaperVisibilityOnAfterEnginUpdate() + }, }, render() { diff --git a/src/components/MapConcernements.vue b/src/components/MapConcernements.vue index afb8458..a5ea1de 100644 --- a/src/components/MapConcernements.vue +++ b/src/components/MapConcernements.vue @@ -42,6 +42,8 @@ export default { paper: null, // mapPopupData: null, + // + superpositions_constraints: [] } }, provide() { @@ -58,7 +60,8 @@ export default { 'concernementsByID', 'opened_concernement', 'opened_entite_id', - 'opened_recit' + 'opened_recit', + 'allSuperpositions' ]), ...mapState(CommonStore,['map_item_ray', 'hover_elmt', @@ -72,13 +75,22 @@ export default { timing: { //timestamp: 0.5, timeScale: 0.5 - } + }, + // constraintIterations: 20, + // positionIterations: 20, + // velocityIterations: 20 } this.engine = Matter.Engine.create(engineOptions); this.engine.gravity.scale = 0; this.world = this.engine.world; + + + // listen for afterUpdate event from Matter.Engine object + Matter.Events.on(this.engine, "beforeUpdate", this.onBeforeEngineUpdate); + Matter.Events.on(this.engine, "afterUpdate", this.onAfterEngineUpdate); }, mounted() { + console.log('map mounted'); this.canvasMap.canvas = this.$refs['canvas-map']; this.canvasMap.ctx = this.canvasMap.canvas.getContext('2d'); @@ -111,6 +123,7 @@ export default { this.setHoverElmt(null); } }.bind(this); + // MATTER let wall_w = 1000; Matter.Composite.add(this.world, [ @@ -203,6 +216,33 @@ export default { } }, deep: true + }, + map_mode: { + handler (n, o) { + console.log('concernementMap watch map_mode', o, n); + if (n === 'superposition' && !this.opened_concernement) { + // create constraints + this.setSuperpositionsMatterConstraints(); + }else{ + // destroy constraints + this.clearSuperpositionsMatterConstraints(); + } + }, + deep: true + }, + allSuperpositions: { + handler (n, o) { + console.log('concernementMap watch allSuperpositions', o, n); + if (n && n.length) { + // create constraints with a delay (watch is needed for first page load) + window.setTimeout(this.setSuperpositionsMatterConstraints, 200); + } + // else{ + // // destroy constraints + // this.clearSuperpositionsMatterConstraints(); + // } + }, + deep: true } }, methods: { @@ -995,6 +1035,98 @@ export default { strokeColor: "#01ffe2", strokeWidth: 0.25, }) + }, + setSuperpositionsMatterConstraints(){ + console.log('setSuperpositionsMatterConstraints this.allSuperpositions', this.allSuperpositions); + // let allBodies = Matter.Composite.allBodies(this.world); + // console.log('allBodies', allBodies); + // let allComposites = Matter.Composite.allComposites(this.world); + // console.log('allComposites', allComposites); + + for(let superposition of this.allSuperpositions){ + // console.log('superposition', superposition[0].cid, superposition[1].cid); + // get the concernement matter bodies with id + let bodyA = Matter.Composite.get(this.world, superposition[0].cid, 'body'); + let bodyB = Matter.Composite.get(this.world, superposition[1].cid, 'body'); + // console.log('bodyA, bodyB', bodyA, bodyB); + + // get the entite coordinates inside the concernement body + let pointA = null; + let concernementA = this.concernementsByID[superposition[0].cid]; + // console.log('concernementA', concernementA); + for(let entiteA of concernementA.revisions_byid[concernementA.active_revision].entites){ + if (entiteA.entite && entiteA.entite.id === superposition[0].eid && entiteA.display) { + // console.log('entiteA', entiteA); + pointA = Matter.Vector.create(entiteA.display.pos.x, entiteA.display.pos.y); + break; + } + } + let pointB = null; + let concernementB = this.concernementsByID[superposition[1].cid]; + // console.log('concernementB', concernementB); + for(let entiteB of concernementB.revisions_byid[concernementB.active_revision].entites){ + if (entiteB.entite && entiteB.entite.id === superposition[1].eid && entiteB.display) { + // console.log('entiteB', entiteB); + pointB = Matter.Vector.create(entiteB.display.pos.x, entiteB.display.pos.y); + break; + } + } + + // console.log(`pointA:`, pointA,` pointB:`, pointB); + if (bodyA && bodyB && pointA && pointB) { + let c = Matter.Constraint.create({ + bodyA: bodyA, + pointA: pointA, + bodyB: bodyB, + pointB: pointB, + stiffness: 1, + length: 0, + damping: 1 + }); + this.superpositions_constraints.push(c); + Matter.Composite.add(this.world, c); + } + } + }, + clearSuperpositionsMatterConstraints(){ + console.log('clearSuperpositionsMatterConstraints', this.superpositions_constraints); + for(let constraint of this.superpositions_constraints){ + Matter.Composite.remove(this.world, constraint, true); + } + this.superpositions_constraints = []; + }, + onBeforeEngineUpdate(){ + + }, + onAfterEngineUpdate(){ + + // // START OF DEBUGGING + // // draw lines of constraints for debuging + // let constraints_lines = this.paper.project.getItem({name: 'constraints_lines', class: paper.Group}); + // if (constraints_lines) { + // constraints_lines.removeChildren(); + // }else{ + // constraints_lines = new paper.Group({ + // pivot: new paper.Point({x:0,y:0}), + // name: 'constraints_lines', + // }); + // } + // let all_constrains = Matter.Composite.allConstraints(this.world); + // let children = []; + // for(let constraint of all_constrains){ + // // console.log('constrain', constraint); + // let pointAWorld = Matter.Constraint.pointAWorld(constraint); + // let pointBWorld = Matter.Constraint.pointBWorld(constraint); + // // console.log('pointAWorld, pointBWorld', pointAWorld, pointBWorld); + // children.push(new paper.Path.Line({ + // from: [pointAWorld.x, pointAWorld.y], + // to: [pointBWorld.x, pointBWorld.y], + // strokeColor: '#f00', + // strokeWidth: 1 + // })); + // } + // constraints_lines.addChildren(children); + // // END OF DEBUGGING } }, beforeUpdate () { diff --git a/src/stores/concernements.js b/src/stores/concernements.js index 46dd985..8919084 100644 --- a/src/stores/concernements.js +++ b/src/stores/concernements.js @@ -97,27 +97,44 @@ export const ConcernementsStore = defineStore({ let already_recorded = false; // loop through all already recorded superposition to complete the array instead of create duplicates for(let superposition of this.allSuperpositions) { - if (superposition.indexOf(entite_superpose.id) >= 0) { - already_recorded = true; - if (superposition.indexOf(entite.entite.id) < 0) { - superposition.push(entite.entite.id) + // if (superposition.indexOf(entite_superpose.id) >= 0) { + // already_recorded = true; + // if (superposition.indexOf(entite.entite.id) < 0) { + // superposition.push(entite.entite.id) + // } + // break; + // } + // if (superposition.indexOf(entite.entite.id) >= 0) { + // already_recorded = true; + // if (superposition.indexOf(entite_superpose.id) < 0) { + // superposition.push(entite_superpose.id) + // } + // break; + // } + for(let superposition_item of superposition) { + if (superposition_item.eid === entite.entite.id && !superposition_item.cid) { + console.log(`already_recorded, eid:${entite.entite.id}, teid:${entite_superpose.id}`, entite.entite.title); + already_recorded = true; + superposition_item.cid = concernement.id; + break; } - break; } - if (superposition.indexOf(entite.entite.id) >= 0) { - already_recorded = true; - if (superposition.indexOf(entite_superpose.id) < 0) { - superposition.push(entite_superpose.id) - } + if (already_recorded) { break; } } // if not already recorded, add it to the array if (!already_recorded) { - // console.log(`NOT already_recorded, eid:${entite.entite.id}, teid:${entite_superpose.id}`, this.allSuperpositions); + console.log(`NOT already_recorded, eid:${entite.entite.id}, teid:${entite_superpose.id}`, entite.entite.title); this.allSuperpositions.push([ - entite.entite.id, // entite id - entite_superpose.id // target id + { + cid: concernement.id, + eid: entite.entite.id + }, + { + cid: null, + eid: entite_superpose.id + } ]) } })