|
|
|
@ -2101,19 +2101,48 @@ function collideTwoElements(elementA, elementB, compatible=true){ // dropping b |
|
|
|
|
dir.subVectors( a, b ).normalize() |
|
|
|
|
if (!compatible){ |
|
|
|
|
elementB.object3D.position.add( dir.multiplyScalar(-1)) // repulsive |
|
|
|
|
// should be clamped, e.g maximum .1 unit bouncing |
|
|
|
|
} else { |
|
|
|
|
elementB.object3D.position.copy( a ) |
|
|
|
|
vol.setFromObject( elA.object3D ) |
|
|
|
|
elementB.object3D.position.x += (vol.max.x - vol.min.x) // snapping equivalent |
|
|
|
|
let width = (vol.max.x - vol.min.x) |
|
|
|
|
// should check first is unoccopied, otherwise move further until empty |
|
|
|
|
elementB.object3D.position.x += width // snapping equivalent |
|
|
|
|
// then can also test for larger structures |
|
|
|
|
// e.g H2O chain "../content/WaterBottle.glb" // by sirkitree (CC-BY) |
|
|
|
|
// can rely on getClosestTargetElement() with the before/after position |
|
|
|
|
// by default .05 threshold |
|
|
|
|
let presentAtoms = {H:0, O:0, C:0} |
|
|
|
|
presentAtoms[ elementA.getAttribute("value") ]++ |
|
|
|
|
presentAtoms[ elementB.getAttribute("value") ]++ |
|
|
|
|
let before = a.clone() |
|
|
|
|
before.x -= width |
|
|
|
|
let after = a.clone() |
|
|
|
|
after.x += width*2 // one of them is a duplicate... might be already positioned correctly before? |
|
|
|
|
presentAtoms[ getClosestTargetElement( before ).getAttribute("value") ]++ |
|
|
|
|
presentAtoms[ getClosestTargetElement( after ).getAttribute("value") ]++ |
|
|
|
|
const compoundChemistryExamples = [ {atoms:{H:2, O:1, C:0},name:"water",url_model:"../content/WaterBottle.glb"} ] |
|
|
|
|
console.log( presentAtoms, compoundChemistryExamples[0] ) |
|
|
|
|
compoundChemistryExamples.map( x => { |
|
|
|
|
console.log("comparing", x.atoms, presentAtoms) |
|
|
|
|
if ( |
|
|
|
|
|
|
|
|
|
Object.keys(x.atoms).map( k => x.atoms[k] <= presentAtoms[k] ) // simplified, should be exact match |
|
|
|
|
.reduce( (a,b) => (a&&b) ) |
|
|
|
|
){ |
|
|
|
|
console.log( x.name, "found", x.url_model,"to display") |
|
|
|
|
addGltfFromURLAsTarget( x.url_model, .1 ) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* testing |
|
|
|
|
elA = addBlockCodeExample('O', '-0.2 1.4 -0.2') |
|
|
|
|
elB = addBlockCodeExample('H') // need few milliseconds to create before testing, so no copy/paste |
|
|
|
|
collideTwoElements(elA, elB) |
|
|
|
|
collideTwoElements(elA, elB, false) |
|
|
|
|
|
|
|
|
|
elA = addBlockCodeExample('O', '-0.2 1.4 -0.2'); elB = addBlockCodeExample('H'); elC = addBlockCodeExample('H', '0.2 1.4 -0.2') |
|
|
|
|
collideTwoElements(elA, elB); collideTwoElements(elB, elC); |
|
|
|
|
|
|
|
|
|
add a new component to see if a group has been modified |
|
|
|
|
means creating first an entity to receive that component and as children the other entities |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
function addBlockCodeExample(text="hi", pos="0 1.4 -0.2", color="black", outlineColor="white"){ |
|
|
|
|