The idea is to drive properties like scale if an specific objects is inside a give BVH volume.
2 Answers
(May consider changing the correct answer to this or similar. Also the first not being a reliable method.)
As of Animation Nodes version 1.5, there is a dedicated node called bvh is inside volume .
.
This works like:
- have a mesh as Bmesh or Mesh data (vector list, polygon indices)
- create bvh tree (out of bmesh or mesh data)
- use the is inside volume to check
- +use others for further refinement, like bvh nearest surface point for distance, normal (for orientation) etc
- to check if On Surface, use bvh nearest surface point and see if distance = 0. (Should use math/round 4 on the distance to avoid precision issues, false negatives)
for example, in the pics I use a grid of cubes and scale if inside. So I check if center of cubes / grid is inside and also the distance for further smooth:
- the grid arrange template, with the cube object
- make a bvh tree of a torus [kdtree and bvhtree / create bvh tree]
- use is inside to switch [boolean / switch] the scale value
- in the second, add distance to smooth the scale transition [kdtree and bvhtree / nearest surface point][number / map range]
(basically, in the second, I use distance, but eliminate the ones outside)
extra / distance
notes:
.The is inside is considering a closed mesh without degenerate features. (It calculates by shooting rays and counting how many times it traverses the mesh surfaces, the so called even /odd method)
.The orientation of faces, normals are irrelevant. This does not use normals to determine positive/negative side of the faces (that is another method, less reliable).
.For using normals, if the case, use nearest surface point that also gives the normal and polygon index, to use further like:
[vector dot] node [point / normal] can give you the sign of the distance and
[vector distance to plane] (same [geometry project point on plane]) will give signed (+/-) distance,
[vector distance to line] (same [geometry project point on line]) can also give a factor in relation to normal, 0-1 etc
. For On Surface, have to see if (rounded 4) distance to nearest is 0
In general if statements are a bit difficult to implement still, but checking wether are a point is inside a volume is (at least partially) possible.
Note: The solution I present here will give 'random' results if the mesh has no volume. Also it doesn't check if the whole object is inside the volume (it only checks the location vector of the object).
The main idea is to take the location of the object and shoot a ray in a random direction. If a polygon in the bvh tree is hit we have to compare the normal of the polygon with the direction of the ray. If the angle between both is lower than 90° we know that the location of the object is inside of the mesh. If it's larger the point is outside.
Let's model this idea with nodes:
Create a new group with the inputs and outputs that you'll need.
Make the shoot a ray in a random direction and calculate the angle between the normal and the ray direction.
Due to the fact that the angle will be zero if the ray doesn't hit any polygon we have to check that both is true: The ray hits a face AND the angle is lower than 90°.
Here is an example on how you can use this group:
ps: For the next release of the Animation Nodes I'll write a node that does the same thing as the group here.
-
$\begingroup$ This is not reliable when the resulting point is on edge or vertex, as the normal extracted can be of another poly than expected and the point can fall "under" that face. See here. github.com/JacquesLucke/animation_nodes/issues/… ! Also, the bvh raycast is in V 1.5 and only works without crash if u use Blender v 2.77! $\endgroup$– o.g.Mar 9, 2016 at 15:18
-
$\begingroup$ oh thanks, I forgot that we implemented the bvh stuff only a few weeks ago because I developed it so many months ago already.. $\endgroup$ Mar 9, 2016 at 15:21
-
$\begingroup$ Great. My idea was to create a grid of objects and scale them as they are included inside of the volume of some animated objects. The problem is that the change of scale will be always very abrupt. But with the reassing loop paramter I will at least recover the previous state of the object. Maybe with some hacking (by creating a vector list) I can recover more than 2 states. As always thanks for your kindness. $\endgroup$ Mar 9, 2016 at 16:06