Using .setControlArea with EasyCam, changing EasyCam's default controls, and setting Easy cam to rotate about the center of the control area

Hello All,

I’m creating a simulation/ program where students can connect different atoms together to start a chemical reaction, thus creating a compound. EX: combining hydrogen and oxygen atoms to get water.

The basic UI of the program will consist of 2 main panels. On the right side will be a small, slim panel which will serve as an element bank. The left side will be the student’s workspace. What I’d like is for students to be able to drag and drop elements from the ‘element bank’ panel, and into their workspace so that they could connect them to form compounds.

I have already implemented the drag and drop feature. What I’d like is to be able to to drag elements (they’re just spheres) from the panel on the left, in to the main workspace, and allow students to work with them in a 3D environment.

I’ve ran into the following issues:

  1. When I drag and drop an element into the control area, I can’t interact with it in a 3D manner. Unless I include it in between the cam.begin & cam.end section. The issue with that is that it takes away from the drag and drop functionality and arises other issues.

  2. Secondly, I’m not sure if I’m using the set control area function correctly because I can still use the mouse inputs to interact with the 3D space, even if my mouse is outside the 3D environment.

  3. Is there anyway I can set the camera to always rotate about the center of the control area. I’ve tried achieving this using the .setOrientation, but it hasn’t been working.

  4. Lastly, is there any way I can alter the default controls to Easy Cam. I’d like for left click to do nothing, scroll wheel to zoom, and right click to rotate.

Thank you for listening. Any advice would be greatly appreciated. I’ll upload my code (It’s not much, aside from the standard stuff its 40-50 lines tops).

The code: Elements.cpp (721 Bytes) Elements.h (241 Bytes) main.cpp (341 Bytes) ofApp.cpp (2.4 KB) ofApp.h (672 Bytes)

You can do all that you are mentioning, and it is quite simple actually.
1.- The control area and the camera´s viewport(the rectangle into which it is drawn) work very close together. If you are not drawing the camera into an fbo then the control area is not necesary, you just need to pass a rectangle to cam.begin.

ofRectangle viewport(20,2,2,2);

This will do several things; first it set’s the cameras viewport thus creating the appropriate transform matrices so perspective looks correctly within that rectangle, then it sets the control area if you have not set it using the setControlArea function. by default this will make the camera rotate around the center.
Note that the camera actually does not rotate around the center of the viewport but around a target (either an ofNode or a 3D position in space). you can set such with setTarget(...).

for drag and drop you can simply use the

// this considers viewport is an ofRectangle instance.
if(viewport.inside(ofGetMouseX(), ofGetMouseY()))
// dropped inside the cameras viewport.

// or you can use it inside one of the the mouse callbacks (mouseReleased, mouseDragged, etc)

In order to determine where the object was dropped in the cameras 3D space, ofEasyCam has several coordinate trasnform functions , in this case you want to use .screenToWorld(...)

You can change the default mouse interactions, read the following write up I made about this feature

As advice, you should make your atoms with either an ofNode, a custom class that inherits from ofNode or an ofSpherePrimitive (which inherits from ofNode) as of node is designed to allow parenting and handles all the transformations for you, so at the moment you join 2 atoms these can become parented by some other element but manipulating each will be much easier from the coding perspective. Take a look at the examples/3d and examples/gl, as there are several useful examples.

Last but not least, please, instead of posting your code as files , just copy and paste the code directly into the editor, then select the code and press the </> button, which is in the toolbar of the forum’s text editor.

1 Like

Thank you so much @roymacdonald , this is exactly what I’m looking for. I don’t know too much about Node’s or 3D primitive, but I’ll definitely look into it. And next time I will be sure to copy my code into the text editor rather than uploading the files. Thanks!!!

Hi, glad that it was helpful.
Take a look at the examples/3d/cameraParentingExample which shows how parenting works. The ofEasyCam, inherits from ofNode, so you can actually make it the child or parent of any other ofNode.
The 3d primitives also inherit from ofNode, but in this case it provides easier mechanism for rendering different 3d shapes. As you mentioned you want to use just spheres so the ofSpherePrimitive would be perfect for what you need. check the example in examples/3d/3DPrimitivesExample. Also check the examples/3d/ofNodeExample
In short, ofNode is a class that stores space transformations (rotation, translation and scale) and has children nodes and a single parent node. each node inherits the transformations from its parent. This allows you to create complex interdependent transformations very easily. As well ofNode provides a lot of utility functions for dealing with these space transformations. For instance, in examples/3d/ofNodeExample, you create a car which inherits from ofNode, and it contains several other ofNodes, you move each of these nodes, like the lights relative to the car, so these are positioned correctly, but then if you want to move everything, the car, you simply change the position of the car, and as the lights’ parent is the car, these will move with the car. Think of of the car as teh molecule and the lights each atom. you only need to set the position of each atom within the molecule once, but the you can move around, rotate and scale the molecule without affecting the relationship between the molecule’s atoms yet moving these around with the molecule?

hope this helps. Let me know how it goes. I am just curious. I like chemestry and I know a bit of it so I can give you a hand if you need