How can I run code on view-change
-
Hi,
Can code keep on running in the background or can plugins only be run from a user command and need to finish before you can continue to work on the model?
Or how can I write a Ruby plugin that is some event, like changing the viewing-angle?
thank you
-
Event driven is best for a GUI application. (Responding to what the user is doing.)
This is done in SketchUp Ruby with observers. Check out all the various observer classes.. which have event callbacks that the SketchUp engine will call.
-
thanks!
-
I found out how to trigger a method when the viewing angle has changed, but I can't seem to find how to know in which viewing direction the window is.
`
class MyViewObserver < Sketchup;;ViewObserver def onViewChanged(view) puts view.camera.eye.to_s end end Sketchup.active_model.active_view.add_observer(MyViewObserver.new)
`
I would like to know the current viewing angle X, Y, Z and compare this to a face if that face is visible on that side or not.
Any idea how to do that?
thanks
-
Just a sidenote. If you are only after watching orbiting, you could use tool resume(view) method. It fires after orbiting or pan and zoom as well. Then you might not need any observer.
You could set a methodcall in there instead..What do you mean face visible ? Reversed ?
Havent done any code for checking face reversed, so I'm just speculating.
I'd reckon it will be unpredictable. Think there are some plugins for this already?
Maybe TIG's orient faces or such..But you could project a ray(view pickray I think?) to the face and compare that vector to the face.normal to within some tolerance. That tolerance would be the hard part, I guess.
But needed since view ray will not be parallel to the face normal all of the time..
Then set conditions comparing vector directions. -
The camera has a .eye and a .target
direction = camera.eye.vector_to(camera.target)
BUT there's also the simpler:
direction = camera.direction
Now the face has a a vector 'normal':
normal = face.normal
If the angle between the 'direction' and the 'normal' are < 90.degrees then you are either 'behind' the face looking towards it, or 'in front' of it looking away from it. At == 90.degrees you are 'edge on'.
` angle = direction.angle_between(normal)
facing = true if if angle > 90.degreesetc`
If you are checking that the camera is looking 'directly at' the face... then use
rayt = model.raytest([camera.eye, direction])
this returnnil
if no hit at all, or a[point, array_of_objects]
- thehit = rayt[1][-1]
return what was hit, so:
` if hit == face || face.edges.include?(hit)etc`
This tells you if the camera is looking at the face and from the 'angle' if the face is facing the camera or turned away from it...
Additional raytesting can also check for intervening objects if you want them to be considered 'transparent'...
` ### Make a loop...
rayt = model.raytest([camera.eye, direction])
while rayt || rayt[1][-1] != face
rayt = model.raytest([rayt[0], direction])
endafter the loop...
hit = true if rayt && rayt[1][-1] == face
This keeps 'mining' through until it hits nothing '
nil' OR '
face' is encountered, THEN if needed check the
angle > 90.degrees` etc -
Nice. I knew someone had done this..
That looks like it will be fairly predictable ? -
thanks!
Advertisement