Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

cellox

select, drag, modify

This topic is 5665 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have problem about picking, selection with special issue which is "drag and modify" selected object in OpenGL... Helps, tutorials suggestions or references will greatly be appreciated... Thanx you all...

Share this post


Link to post
Share on other sites
Advertisement
I once did sth with picking and selecting in opengl.
I was so excited about several exercises i did for
my computer graphic lessons, so i wrote a
strategy-game-style-low-graphic-demonstration:


    
// glutSelect.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung.

//


// #include "stdafx.h"
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


#define EDGE 20.0

double sq(double n)
{
return n * n;
}

struct POINT
{
double x, y;
};

class CRect
{
public:
double x, y;
double ax, ay;

double width, height;

double r, g, b;

bool selected;
bool mouseover;

CRect()
{
// position

x = 0.0;
y = 0.0;

// destination

ax = x;
ay = y;

// measures of rect

width = EDGE;
height = EDGE;

// color

r = 1.0;
g = 1.0;
b = 1.0;

selected = false;
mouseover = false;
}

void move()
{
// if position != destination, move the damn rect

if (abs(x - ax) > 0.2 && abs(y - ay) > 0.2)
{
// compute dot product; dont know the english expression

double skalar = sqrt(sq(ax - x) + sq(ay - y));

// the uniformed (normalized?) vector

POINT d = {(ax - x) / skalar, (ay - y) / skalar};

// move the rect in the vector's direction

x += d.x;
y += d.y;

// just for the record:

// it would be better to make

// these calculations once

// since the dx, dy stay constant

}
glutPostRedisplay();
}

void draw()
{
// color depends on state

if (selected) // red

glColor3d(1.0, 0.0, 0.0);
else
if (mouseover) // green

glColor3d(0.0, 1.0, 0.0);
else // white

glColor3d(r, g, b);

glBegin(GL_POLYGON);

glVertex2d(x, y);
glVertex2d(x + width, y + height);
glVertex2d(x, y + height);

glVertex2d(x, y);
glVertex2d(x + width, y);
glVertex2d(x + width, y + height);

glEnd();
}
};

POINT select;
POINT cursor;
POINT center;

int screen_height = 500;
int screen_width = 500;

// selecting variables

bool selecting = false;
bool add_select = false;

// the reckless rects

CRect rect[25];

void keyboard(unsigned char key, int x, int y)
{
if (key == 27)
exit(0);
}

void display(void)
{
glClearColor(0.4, 0.4, 0.4, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// draw all rects

for (int i = 0; i < 25; i++)
rect[i].draw();

// Draw Select Box here from stored select position to current cursor position

glColor3d(1.0, 1.0, 1.0);
if (selecting)
{
glBegin(GL_LINES);
// upper border

glVertex2f(select.x, select.y);
glVertex2f(cursor.x, select.y);

// right border

glVertex2f(cursor.x, select.y);
glVertex2f(cursor.x, cursor.y);

// lower border

glVertex2f(cursor.x, cursor.y);
glVertex2f(select.x, cursor.y);

// left border

glVertex2f(select.x, cursor.y);
glVertex2f(select.x, select.y);
glEnd();
}

glutSwapBuffers();
}

void reshape(int width, int height)
{
screen_width = width;
screen_height = height;

glViewport(0, 0, width, height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluOrtho2D(0.0, width, height, 0.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

// is value bet between a and b?

// important for select testing

bool between(int bet, int a, int b)
{
if (a <= bet && bet <= b ||
b <= bet && bet <= a)
return true;
else
return false;
}

// tests wether a rect is inside the select box

bool selected(int i)
{
return (between(rect[i].x, select.x, cursor.x) &&
between(rect[i].y, select.y, cursor.y));
}

// important for rects holding formation while moving

POINT avg()
{
POINT avg = {0.0, 0.0};
int sum = 0;

for (int i = 0; i < 25; i++)
{
if (rect[i].selected)
{
avg.x += rect[i].x;
avg.y += rect[i].y;

sum++;
}
}

if (sum != 0)
{
avg.x /= sum;
avg.y /= sum;
}
else
{
avg.x = 0.0;
avg.y = 0.0;
}

return avg;
}

// tests wether mouse cursor is inside a rect

// important for click testing

bool mouseover(int i)
{
return (between(cursor.x, rect[i].x, rect[i].x + rect[i].width) &&
between(cursor.y, rect[i].y, rect[i].y + rect[i].height));
}

void mouse(int button, int state, int x, int y)
{
cursor.x = x;
cursor.y = y;

if (button == GLUT_LEFT_BUTTON)
{
// if left mouse button is pressed or clicked

if (state == GLUT_DOWN)
{
selecting = true;

// test wether CTRL is pressed

// important for add-selecting

add_select = false;
int mod = glutGetModifiers();
if (mod == GLUT_ACTIVE_CTRL)
add_select = true;

// if CTRL is pressed, dont unselect selected rects

if (!add_select)
{
for (int i = 0; i < 25; i++)
rect[i].selected = false;
}

// store current cursor position in variable select

select.x = cursor.x;
select.y = cursor.y;
}
else
{
// left button is released

// no more selecting

selecting = false;

// if the cursor is inside a rect and the rect is not selected

// select it

// otherwise deselect it

for (int i = 0; i < 25; i++)
{
if (mouseover(i))
{
if (!rect[i].selected)
rect[i].selected = true;
else
rect[i].selected = false;
}
}

}
}

// right button: sets destination for the rects

if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
// compute center of all selected items

// check avg() for code

center.x = avg().x;
center.y = avg().y;

// for every selected rect, set the destination point

// the current cursor position (x,y) is the destination point for center

// for destination point of a rect, calculate dx,dy from rect to center

// and add (dx, dy) to the current cursor position

// the computed value is the destination point of a rect!!

for (int i = 0; i < 25; i++)
{
if (rect[i].selected)
{
rect[i].ax = x - (center.x - rect[i].x);
rect[i].ay = y - (center.y - rect[i].y);
}
}
}
glutPostRedisplay();
}


void mouseMotion(int x, int y)
{
// updates the selected/unselected state of the rects

if (selecting)
{
for (int i = 0; i < 25; i++)
{
// check if rect is inside select box

if (selected(i))
rect[i].selected = true;
else
rect[i].selected = false;
}

// update cursor position

cursor.x = x;
cursor.y = y;
}

glutPostRedisplay();
}

void mousePassiveMotion(int x, int y)
{
// update cursor position if no button is pressed

cursor.x = x;
cursor.y = y;

// checks for mouseover event, should be obvious

for (int i = 0; i < 25; i++)
{
if (mouseover(i))
rect[i].mouseover = true;
else
rect[i].mouseover = false;
}
glutPostRedisplay();
}

void idle()
{
// move the rects, if necessary:

// if (position != destination)

// check for code in move()

for (int i = 0; i < 25; i++)
{
rect[i].move();
}
}

int main(int argc, char* argv[])
{
for (int i = 0; i < 25; i++)
rect[i] = CRect();

cursor.x = cursor.y = 0.0;
select.x = select.y = 0.0;
center.x = center.y = 0.0;

//counter for rects

int r = 0;

// (i,j) initial positions of rects

for (i = 10 * EDGE; i < 20 * EDGE; i += 2 * EDGE)
{
for (int j = 10 * EDGE; j < 20 * EDGE; j += 2 * EDGE)
{
rect[r].x = i;
rect[r].y = j;
rect[r].ax = i;
rect[r].ay = j;

r++;
}
}

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screen_height, screen_width);
glutInitWindowPosition(100, 100);
glutCreateWindow("Select - Rahmen");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutIdleFunc(idle);

glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutPassiveMotionFunc(mousePassiveMotion);

glutMainLoop();

return 0;
}


Hold CTRL for add selecting as noted in the code.
There are some leaks in the selection, but i'm too lazy,
to stuff them.

[edited by - Christian Schlager on February 10, 2003 9:13:14 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!