www.jpct.net
jPCT-AE - a 3d engine for Android => Support => Topic started by: marat on June 29, 2011, 10:11:03 am
-
Hallo!
I want to solve the following problems:
1) How to rotateY() 3D object in world space by 2D mouse coordinates? // 3D object must follow mouse movements
2) How to move 3D object in world space by 2D mouse cooridnates? // 3D object must move in world by mouse click
//Solution 1
SimpleVector mouse3D = Interract2D.reproject2D3DWS(camera, xMouse, yMose).normalize();
float angel = mouse3D.calcAngel(my3Dobject);
my3Dobject.clerRotation();
my3Dobject.rotaYAxis(new SimpleVector(0,1,0), angel);
//Solution 2
SimpleVector mouse3D = Interract2D.reproject2D3DWS(camera, xMouse, yMose).normalize();
Simple direction = mouse3D.calcSub(my3Dobject.getTranslation()); // get direction of 3Dobject
my3Dobject.translate(direction.x+1, 0, direction.z+1);
Maybe similar topics already exist? (please can send the links)
Sorry for my english.
Thanks!
[attachment deleted by admin]
-
Hi!
I'm simply made it in Android version with
my3Dobjct.rotateY(turnRad);
where turnRad - is in angle in Radians.
-
So the solutins is?
SimpleVector mouse3D = Interract2D.reproject2D3DWS(camera, xMouse, yMose).normalize(); // Am correctly use method to convert 2D mouse coordinates from screen to 3D?
float angel = mouse3D.calcAngel(my3Dobject);
my3Dobject.clerRotation();
my3Dobject.rotaY(Math.toRadian(angel));
i always got positive angel...
-
I'm not sure, if this is what you mean, but here's an old and hacky test case of mine. It's for desktop jPCT, but it can easily be ported.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import com.threed.jpct.*;
import com.threed.jpct.util.Light;
public class MouseFollowDemo
extends JFrame
implements MouseMotionListener, MouseListener
{
private static final long serialVersionUID = 1L;
private Graphics g = null;
private FrameBuffer fb = null;
private World world = null;
private Object3D plane = null;
private Object3D ramp = null;
private Object3D player = null;
private Object3D cube2 = null;
private Object3D sphere = null;
private boolean doloop = true;
private boolean pressed = false;
private int mouseX = 320;
private int mouseY = 240;
public MouseFollowDemo()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setSize(640, 480);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
addMouseMotionListener(this);
addMouseListener(this);
g = getGraphics();
}
@Override
public void mouseMoved(MouseEvent m)
{
mouseX = m.getX();
mouseY = m.getY();
}
@Override
public void mouseDragged(MouseEvent m)
{}
@Override
public void mouseClicked(MouseEvent e)
{}
@Override
public void mouseEntered(MouseEvent e)
{}
@Override
public void mouseExited(MouseEvent e)
{}
@Override
public void mousePressed(MouseEvent e)
{
pressed = true;
}
@Override
public void mouseReleased(MouseEvent e)
{}
private void initStuff()
{
fb = new FrameBuffer(640, 480, FrameBuffer.SAMPLINGMODE_NORMAL);
world = new World();
fb.enableRenderer(IRenderer.RENDERER_SOFTWARE);
ramp = Primitives.getCube(20);
ramp.setAdditionalColor(Color.red);
plane = Primitives.getPlane(20, 10);
plane.setAdditionalColor(Color.GREEN);
sphere = Primitives.getSphere(30);
sphere.setAdditionalColor(Color.CYAN);
sphere.translate(-50, 10, 50);
cube2 = Primitives.getCube(20);
cube2.setAdditionalColor(Color.ORANGE);
cube2.translate(60, -20, 60);
plane.rotateX((float) Math.PI / 2f);
ramp.rotateX((float) Math.PI / 2f);
player = Primitives.getCone(3);
player.rotateX((float) Math.PI / 2f);
player.rotateMesh();
player.clearRotation();
plane.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
ramp.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
sphere.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
cube2.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
world.addObject(plane);
world.addObject(ramp);
world.addObject(sphere);
world.addObject(cube2);
world.addObject(player);
player.translate(-50, -10, -50);
Light light = new Light(world);
light.setPosition(new SimpleVector(0, -80, 0));
light.setIntensity(40, 25, 22);
world.buildAllObjects();
}
private void lookAt()
{
SimpleVector mousePos = getWorldPosition();
if (mousePos != null)
{
SimpleVector curPos = player.getTranslation();
mousePos = mousePos.calcSub(curPos);
player.setRotationMatrix(mousePos.getRotationMatrix());
}
}
private void relocate()
{
SimpleVector pos = getWorldPosition();
if (pos != null)
{
player.clearTranslation();
player.translate(pos);
}
}
private SimpleVector getWorldPosition()
{
SimpleVector pos = null;
SimpleVector ray = Interact2D.reproject2D3DWS(world.getCamera(), fb, mouseX, mouseY);
if (ray != null)
{
SimpleVector norm = ray.normalize();
float f = world.calcMinDistance(world.getCamera().getPosition(), norm, 1000);
if (f != Object3D.COLLISION_NONE)
{
pos = new SimpleVector();
SimpleVector offset = new SimpleVector(norm);
norm.scalarMul(f);
norm = norm.calcSub(offset);
pos.add(norm);
pos.add(world.getCamera().getPosition());
}
}
return pos;
}
private void doIt()
throws Exception
{
Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 100);
cam.moveCamera(Camera.CAMERA_MOVEUP, 160);
cam.lookAt(plane.getTransformedCenter());
world.getLights().setOverbrightLighting(Lights.OVERBRIGHT_LIGHTING_DISABLED);
while (doloop)
{
lookAt();
if (pressed)
{
relocate();
pressed = false;
}
fb.clear();
world.renderScene(fb);
world.draw(fb);
fb.update();
fb.display(g);
Thread.sleep(10);
}
fb.disableRenderer(IRenderer.RENDERER_OPENGL);
System.exit(0);
}
public static void main(String[] args)
throws Exception
{
MouseFollowDemo cd = new MouseFollowDemo();
cd.initStuff();
cd.doIt();
}
}
-
Thanks EgonOlsen!
It's work 100% very well..
Thanks again...
-
Hm!
I still have problems, this example work fine on desktop systems, but on android system emulator it's work not exactly, differences in the mouse coordinates..
Problems with movements, object does not move exactly (always a distance) when you mouse click.
I don't undesrtand why.
-
Which code do you use for handling touch events?
-
Here's a method out of my 'directional pad' class, you'll have to edit the centerX and Y accordingly, but given an X and a Y (and the correct center) this will compute a radian to rotate a model by.
public float computeRadian(float x, float y) {
float touchPointX = x - centerX;
float touchPointY = centerY - y;
double a = Math.sqrt(Math.pow(touchPointX, 2) + Math.pow(touchPointY, 2));
double b = a;
double c = Math.sqrt(Math.pow(touchPointX, 2) + Math.pow(touchPointY - a, 2));
Double torsoRotate = new Double(Math.acos((Math.pow(a, 2) + Math.pow(b, 2) - Math.pow(c, 2)) / (2 * a * b)));
//Logger.log("a: "+a+" c: "+c+" Degree: "+Degree);
//Degree *= 0.0174532925; // Number to put in rotateY()
//cos-1((P122 + P132 - P232)/(2 * P12 * P13))
//where P12 is the length of the segment from P1 to P2, calculated by
//sqrt((P1x - P2x)2 + (P1y - P2y)2)
if (x < centerX) {
torsoRotate *= -1;
}
return torsoRotate.floatValue();
}
So for touch events I do this:
@Override
public boolean onTouchEvent(MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
holdType = 0;
windowX = me.getX();
windowY = me.getY();
if (inGame) {
///If it's in the dpad
//
if (dpadShoot.touched(windowX, windowY)) {
holdType = 1;
}
}
return true;
}
if (me.getAction() == MotionEvent.ACTION_UP) {
return true;
}
if (me.getAction() == MotionEvent.ACTION_MOVE) {
if (holdType == 1) {
Object3D.clearRotation(); //clear the rotation of the model
Object3D.rotateY(computeRadian(me.getX(), me.getY())); //compute the rotation based on the X and Y given from the touchpad
}
return true;
}
try {
Thread.sleep(15);
} catch (Exception e) {
}
return super.onTouchEvent(me);
}
Please note, the second bit of code won't work, I just pulled what I have, removed most of it, and put in some sample code. But the first method I posted took me a good solid two days and no sleep to figure out, and it's flawless, so enjoy.
-
I use this
setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent e) {
switch(e.getAction()) {
case ACTION_MOVE:
xMouse = e.getX();
yMose = e.getY();
break;
}
return true;
}
});
Maybe i should override? ->
@Override public boolean onTouchEvent
-
Hey if what you have works so far why change it eh?
-
Hm!
I still have problems, this example work fine on desktop systems, but on android system emulator it's work not exactly, differences in the mouse coordinates..
Problems with movements, object does not move exactly (always a distance) when you mouse click.
I don't undesrtand why.
Because your mouse coordinates are off? Might be that the status bar sets them off by some amount. Given that the mouse coordinates match the frame buffer coordinates, the collision system is pixel perfect. So it have to be your mouse coordinates (or you did some porting error).
-
Hm!
Problem is solved, thanks to everybody
//correct
class X extends activity {
myGLView.setOnTouchListener(new View.OnTouchListener() {
}
}
//wrong
class X extends activity {
@Oeverride
public boolean onTouch() {
}
}
:)
-
You say my method is wrong, but why does it work on my phone? I don't have my code in front of me but could it be variations in phones?