Jump to content

[SOLVED] 3D overlay objects using WidgetCanvas::setLineTransform


photo

Recommended Posts

The new canvas_02 sample is very interesting to represent 3D elements over all other 3d elements.

In this sample a modelview and projection matrix is created to rotate around a fake cube created with a set of lines.

 

I tried to modify this sample in the following way:

#include <samples/widgets/common/widgets.h>
#include <core/scripts/utils.h> //extra
#include <core/scripts/primitives.h> //extra
/*
*/
Canvas canvas;
/*
*/
class Canvas {

Gui gui;	// gui

WidgetCanvas canvas; // canvas

int lines[0];   // lines

// constructor/destructor
Canvas() {

 gui = engine.getGui();

 // canvas
 canvas = new WidgetCanvas(gui);

 // vertices
 vec3 vertex[] = (
  vec3(-1.0f,-1.0f,-1.0f), vec3( 1.0f,-1.0f,-1.0f),
  vec3( 1.0f, 1.0f,-1.0f), vec3(-1.0f, 1.0f,-1.0f),
  vec3(-1.0f,-1.0f, 1.0f), vec3( 1.0f,-1.0f, 1.0f),
  vec3( 1.0f, 1.0f, 1.0f), vec3(-1.0f, 1.0f, 1.0f),
 );

 // indices
 int indices[] = (
  0, 1, 1, 2, 2, 3, 3, 0,
  4, 5, 5, 6, 6, 7, 7, 4,
  0, 4, 1, 5, 2, 6, 3, 7,
 );

 // lines
 lines.clear();
 forloop(int i = 0; indices.size(); 2) {
  int line = canvas.addLine();
  canvas.addLinePoint(line,vertex[indices[i + 0]]);
  canvas.addLinePoint(line,vertex[indices[i + 1]]);
  lines.append(line);
 }

 gui.addChild(canvas,GUI_ALIGN_OVERLAP | GUI_ALIGN_BACKGROUND);
}
~Canvas() {
 delete canvas;
}

// update
void update() {
 //int width = engine.app.getWidth();
 //int height = engine.app.getHeight();

 //float time = engine.game.getTime();

 // mat4 projection = scale(width / 2.0f,height / 2.0f,1.0f) * translate(1.0f,1.0f,0.0f) * perspective(60.0f,float(width) / height,0.1f,100.0f);
 // mat4 modelview = translate(0.0f,0.0f,-4.0f) * rotateX(time * 64.0f) * rotateZ(time * 32.0f);

 /* Modifications */
 //get modelview and projection from player
 Player player= Unigine::getPlayer();
 mat4 transform = player.getProjection() * player.getModelview();


 foreach(int line; lines) {
  canvas.setLineTransform(line,transform);
 }
}

// save/restore state
void __restore__() {
 __Canvas__();
}
};
/*
*/
void update_scene() {

while(1) {

 canvas.update();

 wait;
}
}
/*
*/
void create_scene() {

canvas = new Canvas();

ObjectMeshDynamic box= Unigine::createBox(vec3(1.0f,1.0f,1.0f));
box.setMaterial("mesh_base","*");
add_editor(box);

return "WidgetCanvas";
}

 

The idea is to render the canvas cube over the mesh cube, but the canvas cube is not correctly rendered.

 

I've tried different things, but I don't understand how setLineTransform() exactly works.

Link to comment
  • 2 weeks later...

We've modified a sample widgets/canvas_02 to demonstrate how you can draw a wireframe of objects (a box in the example). You can check it in the attachment.

 

The trick for setLineTransform() is that you have to translate coordinates from player's clip plane space (where the bottom left corner is (-1,-1) and top right one is (1,1)) to a widget space (where upper left corner is (0,0) and lower right one is(width,hight)). So you need to:

  • flip Y axis
  • translate coordinates to (0,0) for left corner and (2,2) for the right corner
  • scale them by half

I do hope now you understand the idea behind line transformation :)

canvas_02.cpp

Link to comment
×
×
  • Create New...