Open thejmazz opened 8 years ago
Some visual examples of the goal:
With the membrane highlighted, and an example protein bounding box drawn.
600-700ms for a 100x100 grid filled with 4x4 proteins
This is what a simple membrane with simple proteins will look like once populated:
implemented here with 2D true/false array to keep track of available spaces
Tried this. Took 22 secs to test 8 rays (vertices of a cube) for placing a cube on plane. Not scalable, at least without some octrees or other filtering methods, but the 2D array method was much faster.
See Tree-based Data Structures for Triangle Mesh Connectivity Encoding
There will be as many nodes as there are faces in the mesh. Each iteration will pick a random face, check if that protein can fit there, if it can, assign true
to the proper nodes, else, try another face. Go until no more faces available or a desired percentage of faces filled.
Similar to 2D array method, tree of nodes can have true/false values. This assumes the protein will stick vertically with the normal against the polygon face, and then not intersect with proteins around it. Which is an ok assumption, is largely true.
A complication is assigning multiple faces at once.
overlap
from BVH tree in BlenderHow to check if two meshes intersect in python with BVH Tree?
Same as ray intersecting approach, but in Blender.
const goblinBox = new Goblin.RigidBody(new Goblin.BoxShape(2,3,2))
goblinBox.position = new Goblin.Vector3(0, 0, 0)
goblinBox.updateDerived()
let collidee, contactDetails
console.time('goblinRunNoCollision')
collidee = new Goblin.RigidBody(new Goblin.BoxShape(2,3,2))
collidee.position = new Goblin.Vector3(10, 0, 0)
collidee.updateDerived()
contactDetails = Goblin.GjkEpa.testCollision(goblinBox, collidee)
console.log(contactDetails === undefined ? 'No Collision' : 'Collision')
console.timeEnd('goblinRunNoCollision')
console.time('goblinRunWithCollision')
collidee = new Goblin.RigidBody(new Goblin.BoxShape(2,3,2))
collidee.position = new Goblin.Vector3(2, 0, 0)
collidee.updateDerived()
contactDetails = Goblin.GjkEpa.testCollision(goblinBox, collidee)
console.log(contactDetails === undefined ? 'No Collision' : 'Collision')
console.timeEnd('goblinRunWithCollision')
Which gives times like this:
Without console.log
it is much faster, left out of the tests from here on:
But, I just want binary information: Did a collision occur, yes or no?. So, we can strip out the extra EPA based collision details by changing testCollision to take a boolean param binary
to decide whether or not to invest time to running Goblin.GjkEpa.EPA(simplex)
:
testCollision: function( object_a, object_b, binary ) {
var simplex = Goblin.GjkEpa.GJK( object_a, object_b );
if ( Goblin.GjkEpa.result != null ) {
return Goblin.GjkEpa.result;
} else if ( simplex != null ) {
if (!binary) {
// console.log('Only wants binary information')
return Goblin.GjkEpa.result;
} else {
// console.log('Wants EPA info')
return Goblin.GjkEpa.EPA( simplex );
}
}
},
This brings collision times to be even lower than no collisions!
10000 verts, GJK on every box added so far box, ~12 seconds~ 800-1000ms with octree and less object instanciation
Almost done
TM-Section
materialGiven a membrane mesh and a list of proteins, populate the membrane mesh
Given a (relatively) arbitrary geometry:
we would like to populate it with non-intersecting protein meshes. These can be simplified to their bounding box.