--
-- noCollisionCamera
--
-- # Author:  Heady
-- # date: 01.01.2010
-- # update LS17: 26.10.2016
-- # last update: 26.11.2016
--
-- > Not for commercial use  < --
-- > Not allowed for edit - Copyright (C) Heady - www.planet-ls.de < --
--

print("   noCollisionCamera v17.0.3 by Heady - www.planet-ls.de");


function getCollisionDistance()
    if not isCollisionEnabled then
        return false, nil, nil, nil, nil, nil;
    end
    local raycastMask = 32+64+128+256+4096;
    local targetCamX, targetCamY, targetCamZ = localToWorld(rotateNode, transDirX*zoomTarget, transDirY*zoomTarget, transDirZ*zoomTarget);
    local hasCollision = false;
    local collisionDistance = -1;
    local normalX,normalY,normalZ;
    local normalDotDir;
    for _, raycastNode in ipairs(raycastNodes) do
        hasCollision = false;
        local nodeX, nodeY, nodeZ = getWorldTranslation(raycastNode);
        local dirX, dirY, dirZ = targetCamX-nodeX, targetCamY-nodeY, targetCamZ-nodeZ;
        local dirLength = vector3Length(dirX, dirY, dirZ);
        dirX = dirX / dirLength;
        dirY = dirY / dirLength;
        dirZ = dirZ / dirLength;
        local startX = nodeX;
        local startY = nodeY;
        local startZ = nodeZ;
        local currentDistance = 0;
        local minDistance = transMin;
        while (true) do
            if (dirLength-currentDistance) <= 0 then
                break;
            end;
            raycastDistance = 0;
            raycastClosest(startX, startY, startZ, dirX, dirY, dirZ, "raycastCallback", dirLength-currentDistance, self, raycastMask, true);
            if raycastDistance ~= 0 then
                currentDistance = currentDistance + raycastDistance+0.001;
                local ndotd = dotProduct(normalX, normalY, normalZ, dirX, dirY, dirZ);
                if getIsAttachedVehicleNode == nil or getIsDynamicallyMountedNode == nil then
                    break;
                end
                if vehicle:getIsAttachedVehicleNode(raycastTransformId) or getIsDynamicallyMountedNode(raycastTransformId) then
                    if ndotd > 0 then
                        minDistance = math.max(minDistance, currentDistance);
                    end;
                else
                    hasCollision = true;
                    -- we take the distance from the rotate node
                    if raycastNode == rotateNode then
                        normalX,normalY,normalZ = normalX, normalY, normalZ;
                        collisionDistance = math.max(transMin, currentDistance);
                        normalDotDir = ndotd
                    end;
                    break;
                end;
                startX = nodeX+dirX*currentDistance;
                startY = nodeY+dirY*currentDistance;
                startZ = nodeZ+dirZ*currentDistance;
            else
                break;
            end;
        end;
        if not hasCollision then
            break;
        end;
    end;
    return hasCollision, collisionDistance, normalX,normalY,normalZ, normalDotDir;
end;

ModEvent = {};

function ModEvent:noCollisionCamera()
	 return false, nil, nil, nil, nil, nil;
end;


local entry = {};
for splitS in string.gmatch(g_gameVersionNotification, ".") do
	table.insert(entry, splitS);
end;

--if g_gameVersion == 4 then --and ( entry[1] == "1" and entry[3] == "2" ) then
	VehicleCamera.getCollisionDistance = Utils.overwrittenFunction(VehicleCamera.getCollisionDistance, ModEvent.noCollisionCamera);	
--end;
