Jump to content

[Solved]How can I operate the model in the scene through c++ call Unigine API?


photo

Recommended Posts

Hi ,

    I'm a fresh Unigine learner. I have a question about operate the model in the scene. The total function I wanna realize is that :

 

a. I can import a model(.obj) though the C++ call Unigine API(I've realized this function).

b. I can pick one of the models in scene.

c. I can move the model I picked in the scene.

d. I can rotate the model I picked in the scene.

e. I can zoom out and zoom in the model i picked in the scene.

 

please tell me which class can help me to realize those function, Or can you give me some samples?

 

 

Thanks.

Ivy.

 

  • Like 1
Link to comment

Hi,

 

b. To get a node, that mouse cursor points to, you need to get world intersection by mouse direction. Check out WorldIntersection usage example https://developer.unigine.com/en/docs/future/api/library/worlds/class.worldintersection?rlang=usc.

This sample is in unigine script. The main issue here, that in C++ API there is no "getPlayerMouseDirection" method.

 

He have added corresponding functionality to Unigine::Camera class (method Camera::getDirectionFromScreen), it will be available in the next release. You can use the following function so far:

bool getPlayerMouseDirection(Vec3 *p0, Vec3 *p1)
{
	PlayerPtr player = Unigine::Game::get()->getPlayer();
	float mouse_x = Unigine::App::get()->getMouseX();
	float mouse_y = Unigine::App::get()->getMouseY();
	float width = Unigine::App::get()->getWidth();
	float height = Unigine::App::get()->getHeight();
	
	if (player.get() == NULL)
		return false;
	
	mat4 projection = player->getProjection();
	Mat4 imodelview = player->getWorldTransform();

	projection.m00 *= height / width;
	float x = -(mouse_x / width * 2.0f - 1.0f + projection.m02) / projection.m00;
	float y = (mouse_y / height * 2.0f - 1.0f + projection.m12) / projection.m11;

	if (projection.m32 == 0.0f)
	{
		*p0 = imodelview * Vec3(-x, -y, -1.0f);
		*p1 = imodelview * Vec3(-x, -y, 1.0f);
	} else
	{
		*p0 = Vec3(imodelview.m03, imodelview.m13, imodelview.m23);
		*p1 = imodelview * Vec3(x, y, 1.0f);
	}

	*p1 = *p0 - normalize(*p1 - *p0) * player->getZFar();

	return true;
}

Sorry for inconvenience caused.

 

c,d. When you get your NodePtr you can move and rotate it using transformation matrix and methods Node::(set/get)Transform and Node::(set/get)WorldTransform, the difference here, that world transform operates in global space coordinates, while other in local.

 

e. To zoom in/out (and also to rotate camera around node) you can create PlayerPersecutor, assign it to node by PlayerPersecutor::setTarget, and set it as a game player by Game::setPlayer. Now you can rotate camera by mouse. For changing distances there are corresponding methods setMinDistance, setMaxDistance, setDistance.

Link to comment

Hi maxi,

    Thank you very much for your particular suggestion. 

    About my needs, I wanna explain the last item : "e. I can zoom out and zoom in the model i picked in the scene."    This function I wanna realize is that I can chose one model in the scene(there are many models in the scene) and only zoom in/out the model I selected instead of all models in the scene. so I think I can't rotate camera directly. 

Link to comment

Hi,
    Now I can't chose the model I've load in my code, because I can't remove it's ownnership form code to the editor. I have consulted the UnigineScript's code, but I can't use it in C++ code.

    I saw that UnigineScript realize that by this:

Source code(UnigineScript)
/* declare ObjectMeshStatic objects for nodes 
*/
ObjectMeshStatic box_1;
ObjectMeshStatic box_2;

/* add a mesh as a node to the editor
 */
Node add_editor(Node node) {
	engine.editor.addNode(node);
	return node_remove(node);
}

/* the init() function of the world script file
 */
int init() {
	/* create a camera and add it to the world
	 */
	Player player = new PlayerSpectator();
	player.setDirection(Vec3(0.755f,-1.0f,0.25f));
	engine.game.setPlayer(player);

	// add the box mesh to the editor
	box_1 = add_editor(new ObjectMeshStatic("matrix_project/meshes/box.mesh"));

	// set the transformation and the material for the first box mesh
	mat4 transform = translate(vec3(0.0f,0.0f,0.0f));
	box_1.setWorldTransform(mat4(transform));
	box_1.setMaterial("mesh_base", "*");

	// add the second box mesh to the editor
	box_2 = add_editor(new ObjectMeshStatic("matrix_project/meshes/box.mesh"));
	
	// set the transformation and the material for the second box mesh
	mat4 transform1 = translate(vec3(0.0f,2.0f,1.0f));
	box_2.setWorldTransform(Mat4(transform1));
	box_2.setMaterial("mesh_base", "*");
	
	// add the second box mesh as a child to the first box mesh
	box_1.addChild(box_2);

	// show the transformation matrix and the world transformation matrix of the child node
	log.message("transformation matrix of the child node: %s\n", typeinfo(box_2.getTransform()));
	log.message("world transformation matrix of the child node: %s\n", typeinfo(box_2.getWorldTransform()));

	return 1;
}

He use  

engine.editor.addNode(node)

function and put a ObjectMeshStatic object as the function's argument, so that he add the ObjectMeshStatic object he creat in code to the editor, so that he can operate the object. so how can I turn an ObjectMeshStaticPtr model into NodePtr so that I can remove code's ownnership and add it to editor by use of some function like "node_remove()" and "addNode()" function in the UnigieScript?

 

 

Sorry for my question, I'm a new girl for Unigine Engine.

Thanks.

jiangqiu

Link to comment

Hi, 

 

The owning model is a little bit different in c++. You have smart pointers, that have an owner flag. If owner == 1, pointer deletes node on destruction. When you create an object using create method, an owner pointer is returned, in other cases pointer will not be an owner. Node::grab - takes ownership, node::release - set owner to 0, and node::isOwner returned owner flag.

This is how your code snippet can look like in c++:

Source code(c++)

// private class members
ObjectMeshStaticPtr box_1;
ObjectMeshStaticPtr box_2;

int init() {
	/* create a camera and add it to the world
	 */
	PlayerSpectatorPtr player_spectator = PlayerSpectator::create();
        // player_spectator is an owner pointer here and will be deleted in out of scope, so release it
        player_spectator->release();
	player_spectator->setDirection(Vec3(0.755f,-1.0f,0.25f));

        // get base class player pointer, it will not be an owner
        PlayerPtr player = player_spectator->getPlayer();
	engine.game.setPlayer(player);

	// add the box mesh to the editor
	box_1 = ObjectMeshStatic::create("matrix_project/meshes/box.mesh");
        // box_1 is owner and if you want to add it to editor, release it
        box_1->release();
        Unigine::Editor::get()->addNode(box_1);
        
        // for example we don't add box_2 to editor so owner is fine here
        box_2 = ObjectMeshStatic::create("matrix_project/meshes/box.mesh");

	return 1;
}
  • Like 1
Link to comment
×
×
  • Create New...