Raycast from touch location to 3D space

Hi,
I need to detect the point of intersection of my Sprite3D on touch, so that I can aim for some object like bullet towards the aimed direction on Sprite3D.

Any leads would be greatly appreciated.

Summary: For a prototype I was creating that used a game server, the client application rendered a 3D terrain and a 3D orc object I got from the Cocos2dx samples. To move my orc around on the 3D terrain I created a ray cast from the touch location and found the intersection point on the terrain, I then had to calculate the height of my orc based on the terrain height map so that he would look like he was moving along the top of the terrain. The orcs position and rotation was calculated based on the ray cast intersection point on the terrain and the orcs current position and so he moved to the touch location.

For your use case you want to be able to touch an enemy in the 3D world and have your player fire a bullet directly at it?

You can fire a ray cast from the touch location to the game world, if the ray intersects your enemy, calculate the vector from your player to the enemy and send the bullet along that vector?

This is a snippet of the ray cast implementation I used

void MainScene::onTouchEnded(Touch* touch, Event* event)
{
    // Player movement
    cocos2d::Vec2 touchLocation = touch->getLocation();
    PrintLocation("Touch location", touchLocation.x, touchLocation.y, 0);
    
    // Use the touch location to find an origin point and a direction for a ray cast
    cocos2d::Vec3 nearPosition(touchLocation.x, touchLocation.y, 0.0f);
    cocos2d::Vec3 farPosition(touchLocation.x, touchLocation.y, 1.0f);
    
    CCLOG("Before unproject");
    PrintLocation("Near position", nearPosition.x, nearPosition.y, nearPosition.z);
    PrintLocation("Far position", farPosition.x, farPosition.y, farPosition.z);
    
    auto size = Director::getInstance()->getWinSize();
    _Camera->unprojectGL(size, &nearPosition, &nearPosition);
    _Camera->unprojectGL(size, &farPosition, &farPosition);
    
    CCLOG("After unproject");
    PrintLocation("Near position", nearPosition.x, nearPosition.y, nearPosition.z);
    PrintLocation("Far position", farPosition.x, farPosition.y, farPosition.z);
    
    cocos2d::Vec3 direction(farPosition - nearPosition);
    direction.normalize();
    PrintLocation("Direction", direction.x, direction.y, direction.z);
    
    CCLOG("Creating raycast");
    Vec3 collisionPoint;
    bool isInTerrain = _terrain->getIntersectionPoint(Ray(nearPosition, direction), collisionPoint);
    
    
    if(!isInTerrain)
    {
        CCLOG("Raycast hit the player");
        _OrcState = ORC_IDLE;
    }
    else
    {
        direction = collisionPoint - _Orc->getPosition3D();
        direction.y = 0;
        direction.normalize();
        _headingAngle = -1 * acos(direction.dot(Vec3(0,0,-1)));
        _headingAngle += 135;
        direction.cross(direction,Vec3(0,0,-1), &_headingAxis);
        _targetPos = collisionPoint;
        // forward();
        _OrcState = ORC_FORWARD;
        
    }
    event->stopPropagation();
}


void MainScene::update(float dt)
{
    // Update camera to follow player character
    _Camera->setPosition3D(_Orc->getPosition3D() + Vec3(0, 45, 60));
    //_Camera->lookAt(_Orc->getPosition3D(), Vec3(0, 1, 0));
    
    // Move player
    if(_OrcState == ORC_FORWARD)
    {
        Vec3 curPos = _Orc->getPosition3D();
        Vec3 newFaceDir = _targetPos - curPos;
        newFaceDir.y = 0.0f;
        newFaceDir.normalize();
        Vec3 offset = newFaceDir * 25.0f * dt;
        curPos+=offset;
        _Orc->setPosition3D(curPos);
        
        // transform player position to world coord
        auto playerPos = _Orc->getPosition3D();
        auto playerModelMat = _Orc->getParent()->getNodeToWorldTransform();
        playerModelMat.transformPoint(&playerPos);
        Vec3 Normal;
        float player_h = _terrain->getHeight(playerPos.x, playerPos.z,&Normal);
        if (Normal.isZero()) // check if the player is off the terrain
        {
            player_h = playerPos.y;
        }
        else
        {
            player_h += 0;
        }
        _Orc->setPositionY(player_h);
        Quaternion q2;
        q2.createFromAxisAngle(Vec3(0,1,0),(float)-M_PI,&q2);
        
        Quaternion headingQ;
        headingQ.createFromAxisAngle(_headingAxis,_headingAngle,&headingQ);
        _Orc->setRotationQuat(headingQ * q2);
    }
    
    // Check if orc is at destination
    Vec2 player_pos =Vec2(_Orc->getPositionX(),_Orc->getPositionZ());
    Vec2 targetPos = Vec2(_targetPos.x,_targetPos.z);
    auto dist = player_pos.distance(targetPos);
    if(dist<1)
    {
        _OrcState = ORC_IDLE;
    }
}

Github repo is here https://github.com/damorton/Hydrogen/tree/develop

Hope this helps.

Hi Damort. DO you have any other query examples.
Would you read my post pretty please.


Much appreciated

Thanks a lot.This helped me solve my issue.

Had a read but Im unsure about what you are trying to do exactly. Left a comment on the other thread if you have anymore details, reply there.