Home › Forum › SOFA › Using SOFA › [SOLVED] Attach a spotlight to a rigid body
Tagged: 64_bits, Linux_ubuntu, rendering, SOFA_1906, Spotlight
- This topic has 12 replies, 2 voices, and was last updated 5 years, 2 months ago by bobiko.
-
AuthorPosts
-
19 July 2019 at 11:34 #13970bobikoBlocked
Hi,
I am developing a simulator for endoscopy and I would like to attach a spotlight to the distal tip of the instrument. Now, for instance, if I want to attach a camera to a rigid object, I can create a view port and link it to the object by using
cameraRigid
property. But what is the proper way to do it for a positional light? Thanks in advance.22 July 2019 at 17:56 #13977HugoKeymasterHi @bobiko
and welcome on the SOFA forum!
ViewPort and SpotLight are two different things:- ViewPort (OglViewPort) is a new point of view in the simulation, as you can see in the scene: examples/Components/visualmodel/OglViewport.scn
- SpotLight is a light with a position and direction of light, asyou can see in the scene: examples/Components/visualmodel/SpotLight.scn
Which of those do you want to use ?
Linking the position with the MechanicalObject (of a rigid body for instance) is the good way to go. If you share you scene, we might be able to help a bit more.Best,
hugo
23 July 2019 at 11:17 #13981bobikoBlockedHi @Hugo!
Thank you for your response! I do realize that ViewPort and SpotLight are not realted, it was rather a poor example, pardon me for making it confusing.
My goal is to attach a SpotLight and a ViewPort to the distal part of the instrument in order to mimic behavior of a real endoscope. I managed to attach a ViewPort to the instrument by creating a MechanicalObject and linking it to the instrument with RigidRigid mapping (as I want to attach the ViewPort to the distal part of the instrument, not to its center). To be clear, here is my scene:
<Node name="root" dt="0.005" > <RequiredPlugin name="SofaOpenglVisual" /> <RequiredPlugin pluginName="CImgPlugin" /> <RequiredPlugin name="SofaPython" /> <VisualStyle displayFlags="hideBehaviorModels hideCollisionModels hideMapping hideForceFields" /> <LightManager /> <SpotLight name="LightSource" color="1 1 1" position="0 4 0" direction="0 -1 0" cutoff="10" exponent="1" fixed="1" /> <Gravity name="G" gravity="0 -9.81 0" /> <CollisionPipeline name="pipeline" depth="6" verbose="0" /> <BruteForceDetection name="detection" /> <CollisionResponse name="response" response="FrictionContact" /> <LocalMinDistance name="proximity" alarmDistance="0.04" contactDistance="0.02" angleCone="0.0" /> <FreeMotionAnimationLoop/> <LCPConstraintSolver tolerance="1e-5" maxIt="1000" /> <include name="Uterus" href="uterus_fem.xml" /> <include name="Instrument" href="instrument.xml" position="0 -2 0 0 0 0 1.0"/> <OglViewport screenPosition="0 0" screenSize="300 300" zNear="0.01" zFar="10" cameraRigid="@Instrument/Instrument/Camera/CameraState.position" drawCamera="1" /> </Node>
And here I define the CameraState MechanicalObject in :
... <Node name="Instrument" > <EulerImplicitSolver name="ODE solver" rayleighStiffness="0.05" rayleighMass="1.0" /> <CGLinearSolver name="linear solver" iterations="50" tolerance="1e-10" threshold="10e-10" /> <MechanicalObject name="instrumentState" template="Rigid3d" position="0 0 0 0 0 0 1.0" /> <UniformMass name="mass" totalMass="0.1" /> <UncoupledConstraintCorrection/> <Node name="VisualModel" > <MeshObjLoader name="VisualLoader" filename="mesh/hysteroscope.obj" /> <OglModel name="InstrumentVisualModel" src="@VisualLoader" /> <RigidMapping name="MM->VM mapping" input="@instrumentState" output="@InstrumentVisualModel" /> </Node> <Node name="CollisionModel" > <MeshObjLoader filename="mesh/hysteroscope_for_collision.obj" name="loader"/> <Mesh src="@loader" name="InstrumentCollisionModel" /> <MechanicalObject src="@loader" name="instrumentCollisionState" /> <LineCollisionModel name="instrument" contactStiffness="10" /> <PointCollisionModel name="instrument" contactStiffness="10" /> <TriangleCollisionModel name="instrument" contactStiffness="10" /> <RigidMapping name="MM->CM mapping" input="@instrumentState" output="@instrumentCollisionState" /> </Node> <VectorSpringForceField object1="@Input/RefModel/instrumentCollisionState" object2="@Instrument/CollisionModel/instrumentCollisionState" stiffness="10" viscosity="0" /> <Node name="Camera" > <MechanicalObject template="Rigid3d" name="CameraState" rx="90"/> <RigidRigidMapping /> </Node> </Node> ...
Now, the only thing that’s left is to attach a SpotLigth to the same position and make it move with the instrument. Thus, my question is, is it possible to do something similar to the SpotLight? I mean, can I somehow attach it to a MechanicalObject?
25 July 2019 at 17:59 #13992HugoKeymasterHi @bobiko
I am not sure (since I can not test with your meshes) but I think all you need to do is to shift these to lines:
<OglViewport screenPosition="0 0" screenSize="300 300" zNear="0.01" zFar="10" cameraRigid="@Instrument/Instrument/Camera/CameraState.position" drawCamera="1" /> <SpotLight name="LightSource" color="1 1 1" position="@Instrument/Instrument/Camera/CameraState.position" direction="0 -1 0" cutoff="10" exponent="1" fixed="1" />
at the end of the file like:
<Node name="root" dt="0.005" > <RequiredPlugin name="SofaOpenglVisual" /> <RequiredPlugin pluginName="CImgPlugin" /> <RequiredPlugin name="SofaPython" /> <VisualStyle displayFlags="hideBehaviorModels hideCollisionModels hideMapping hideForceFields" /> <LightManager /> <Gravity name="G" gravity="0 -9.81 0" /> <CollisionPipeline name="pipeline" depth="6" verbose="0" /> <BruteForceDetection name="detection" /> <CollisionResponse name="response" response="FrictionContact" /> <LocalMinDistance name="proximity" alarmDistance="0.04" contactDistance="0.02" angleCone="0.0" /> <FreeMotionAnimationLoop/> <LCPConstraintSolver tolerance="1e-5" maxIt="1000" /> <include name="Uterus" href="uterus_fem.xml" /> <include name="Instrument" href="instrument.xml" position="0 -2 0 0 0 0 1.0"/> <Node name="Instrument" > <EulerImplicitSolver name="ODE solver" rayleighStiffness="0.05" rayleighMass="1.0" /> <CGLinearSolver name="linear solver" iterations="50" tolerance="1e-10" threshold="10e-10" /> <MechanicalObject name="instrumentState" template="Rigid3d" position="0 0 0 0 0 0 1.0" /> <UniformMass name="mass" totalMass="0.1" /> <UncoupledConstraintCorrection/> <Node name="VisualModel" > <MeshObjLoader name="VisualLoader" filename="mesh/hysteroscope.obj" /> <OglModel name="InstrumentVisualModel" src="@VisualLoader" /> <RigidMapping name="MM->VM mapping" input="@instrumentState" output="@InstrumentVisualModel" /> </Node> <Node name="CollisionModel" > <MeshObjLoader filename="mesh/hysteroscope_for_collision.obj" name="loader"/> <Mesh src="@loader" name="InstrumentCollisionModel" /> <MechanicalObject src="@loader" name="instrumentCollisionState" /> <LineCollisionModel name="instrument" contactStiffness="10" /> <PointCollisionModel name="instrument" contactStiffness="10" /> <TriangleCollisionModel name="instrument" contactStiffness="10" /> <RigidMapping name="MM->CM mapping" input="@instrumentState" output="@instrumentCollisionState" /> </Node> <VectorSpringForceField object1="@Input/RefModel/instrumentCollisionState" object2="@Instrument/CollisionModel/instrumentCollisionState" stiffness="10" viscosity="0" /> <Node name="Camera" > <MechanicalObject template="Rigid3d" name="CameraState" rx="90"/> <RigidRigidMapping /> </Node> </Node> <OglViewport screenPosition="0 0" screenSize="300 300" zNear="0.01" zFar="10" cameraRigid="@Instrument/Instrument/Camera/CameraState.position" drawCamera="1" /> <SpotLight name="LightSource" color="1 1 1" position="@Instrument/Instrument/Camera/CameraState.position" direction="0 -1 0" cutoff="10" exponent="1" fixed="1" /> </Node>
Let us know if it helps.
Hugo
28 July 2019 at 14:48 #14010bobikoBlockedThanks very much for the tip! It did work, but only partially, as the light’s position is now attached to the object; however, direction does not change with a change of the instrument’s orientation. As far as I understand, there is no simple way of binding the orientation of the instrument and the direction of light, as the direction is given as a directional vector and not as Euler angles. Or am I missing something?
28 July 2019 at 18:54 #14011HugoKeymasterHi @bobiko
the Rigid MechanicalObject defines one frame: x,y,z + quaternion.
If you want the light to also follow the orientation indeed to solution:
– you can do it with a PythonScriptController by extracting the quaternion info and transform it in a Euler angle to provide to the Camera
– you can implement this in C++. I did it for you in the existing class RigidToQuatEngine. Please find here the git patch to apply: EngineExportOrientationEuler.patch
Note to apply a git patch, just follow git instructions. If it compiles and works for you, could you please pull-request this change in the GitHub repository of SOFA please?Best
Hugo
29 July 2019 at 10:23 #14012bobikoBlockedHi @Hugo,
Thanks for the patch, but as I said, SpotLight direction is defined as a directional vector (for example, the default value (0, 0, -1) points downwards). So I am afraid this patch is not applicable in this case.
I was thinking of adding a<Rigid>
property to SpotLight class in C++, similar tocameraRigid
in OglViewport, thus we can directly attach SpotLight to a rigid object in both position and direction. Do you think it would make sense?Regards,
Vlad29 July 2019 at 10:35 #14013HugoKeymasterHi @bobiko
As you want, but the patch I sent you would expose a directional vector (Euler angles) instead of using the quaternion of the Rigid.
Let us know whenever you make it.Hugo
29 July 2019 at 11:15 #14014bobikoBlockedHi @Hugo,
I tried the patch you sent and, unfortunately, it didn’t work for me. I used the following line to attach the direction of the SpotLight to my instrument:<SpotLight name="LightSource" color="1 1 1" direction="@Instrument/Instrument/Camera/CameraState.position" position="@Instrument/Instrument/Camera/CameraState.position" cutoff="10" exponent="1" fixed="1" />
However, the light still always points the same direction (down). Here is a link to a short demo: https://we.tl/t-SDWR2ppz3q
P.S. Sorry if I don’t fully understand the concepts of SOFA, I am still a newbie, but aren’t direction vector and Euler angles different things? For instance, if I want SpotLight to point up, I set its direction as (0, 1, 0). Contrarily, if I set Euler angles to (0, 1, 0) for some arbitrary object, it would mean 1 degree rotation of that object around Y axis.
29 July 2019 at 15:43 #14022HugoKeymasterHi @bobiko
I tested myself on another computer. It works.
Here is a simplified patch.All you need is to:
– apply this patch (in the sources)git apply EngineExportOrientationEuler.patch
– compile again
– run this example scene:<Node name="root" dt="0.005" > <RequiredPlugin name="SofaOpenglVisual" /> <RequiredPlugin pluginName="CImgPlugin" /> <RequiredPlugin name="SofaPython" /> <VisualStyle displayFlags="hideBehaviorModels hideCollisionModels hideMapping hideForceFields" /> <LightManager ambient="1 1 1 1"/> <Gravity name="G" gravity="0 0 0" /> <DefaultPipeline name="pipeline" depth="6" verbose="0" /> <BruteForceDetection name="detection" /> <DefaultContactManager name="response" response="FrictionContact" /> <LocalMinDistance name="proximity" alarmDistance="0.04" contactDistance="0.02" angleCone="0.0" /> <FreeMotionAnimationLoop/> <LCPConstraintSolver tolerance="1e-5" maxIt="1000" /> <!-- <include name="Uterus" href="uterus_fem.xml" /> --> <!-- <include name="Instrument" href="instrument.xml" position="0 -2 0 0 0 0 1.0"/> --> <Node name="Instrument" > <EulerImplicitSolver name="ODE solver" rayleighStiffness="0.05" rayleighMass="1.0" /> <CGLinearSolver name="linear solver" iterations="50" tolerance="1e-10" threshold="10e-10" /> <MechanicalObject name="instrumentState" template="Rigid3d" position="0 0 0 0 0 0 1.0" showObject="1" showObjectScale="1" /> <UniformMass name="mass" totalMass="0.1" /> <UncoupledConstraintCorrection/> <Node name="VisualModel" > <MeshObjLoader name="VisualLoader" filename="mesh/liver.obj" /> <!-- <OglModel name="InstrumentVisualModel" color="red" src="@VisualLoader" /> --> <RigidMapping name="MM->VM mapping" input="@instrumentState" output="@InstrumentVisualModel" /> </Node> <Node name="CollisionModel" > <MeshObjLoader filename="mesh/liver.obj" name="loader"/> <MeshTopology src="@loader" name="InstrumentCollisionModel" /> <MechanicalObject src="@loader" name="instrumentCollisionState" /> <LineCollisionModel name="instrumentLine" contactStiffness="10" /> <PointCollisionModel name="instrumentPoint" contactStiffness="10" /> <TriangleCollisionModel name="instrumentTriangle" contactStiffness="10" /> <RigidMapping name="MM->CM mapping" input="@instrumentState" output="@instrumentCollisionState" /> </Node> <!-- <VectorSpringForceField object1="@Input/RefModel/instrumentCollisionState" object2="@Instrument/CollisionModel/instrumentCollisionState" stiffness="10" viscosity="0" /> --> <Node name="Camera" > <MechanicalObject template="Rigid3d" name="CameraState" rz="90" /> <RigidToQuatEngine name="EngineExportingOrientationEuler" rigids="@CameraState.position" /> <RigidRigidMapping /> </Node> </Node> <MeshObjLoader name="VisualLoader" filename="mesh/liver.obj" translation="10 -5 -5" /> <OglModel name="FixedVisualModel" src="@VisualLoader" color="blue"/> <OglViewport screenPosition="0 0" screenSize="300 300" zNear="0.01" zFar="10" cameraPosition="@Instrument/Camera/CameraState.position" drawCamera="0" /> <SpotLight name="LightSource" color="0 0 1" position="@Instrument/Camera/CameraState.position" direction="@Instrument/Camera/EngineExportingOrientationEuler.orientationsEuler" cutoff="25" exponent="1" drawSource="0"/> </Node>
As you can see the OglViewport can be directly connected to the Rigid MechanicalObject:
cameraPosition="@Instrument/Camera/CameraState.position"
while the SpotLight needs both the position :
position="@Instrument/Camera/CameraState.position""
and the orientation:
direction="@Instrument/Camera/EngineExportingOrientationEuler.orientationsEuler"
Best,
Hugo
29 July 2019 at 15:59 #14025bobikoBlockedThanks, it did help! Sorry, I totally missed the part about RigidToQuatEngine in the scene before.
23 August 2019 at 09:54 #14145HugoKeymasterHey @bobiko
Did you finally used my patch?
If yes, could you pull request this change? It would be interesting that other developers see and benefit from it.Thanks!
Hugo
16 September 2019 at 08:53 #14238 -
AuthorPosts
- You must be logged in to reply to this topic.