⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.java

📁 基于java的3d开发库。对坐java3d的朋友有很大的帮助。
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
            if ( u > 0 ) {                return new InfinitePlane(right, eyePosition.add(right.multiply(u)));            }            else {                return new InfinitePlane(left, eyePosition.add(right.multiply(u)));            }        }        Vector3D du = rightWithScale.multiply(u);        Vector3D f = new Vector3D(front);        Vector3D dir = du.add(_dir);        f.normalize();        double alpha;        dir.normalize();        alpha = Math.acos(f.dotProduct(dir));        if ( u > 0 ) alpha *= -1;        // 2. Calculate the plane normal        Matrix4x4 R = new Matrix4x4();        Vector3D n;        R.axisRotation(alpha, up);        n = R.multiply(du);        n.normalize();        // 3. Build the plane and return        InfinitePlane plane;        plane = new InfinitePlane(n, eyePosition);        return plane;    }    /**    Given `this` camera and the pixel (x, y) in its viewport, this method    calculates an infinite plane that pass by the corresponding proyector    ray origin and by the proyection plane (u, v) point, where (u, v) is    the proyection of pixel (x, y). The plane is perpendicular to the v    direction.    */    public InfinitePlane calculateVPlaneAtPixel(int x, int y)    {        // 1. Calculate the angle between the front vector and the plane        updateVectors();        double v = ((viewportYSize - (double)y - 1) -  viewportYSize/2.0) / viewportYSize;        return calculateVPlane(v);    }    /**    PRE: updateVectors() must be called before this method if camera model    is new or recently changed.    */    public InfinitePlane calculateVPlane(double v)    {        if ( projectionMode == PROJECTION_MODE_ORTHOGONAL ) {            v /= orthogonalZoom;            v *= 2;            Vector3D up2 = new Vector3D(up);            up.normalize();            if ( v > 0 ) {                return new InfinitePlane(up, eyePosition.add(up.multiply(v)));            }            else {                Vector3D down = up.multiply(-1);                return new InfinitePlane(down, eyePosition.add(up.multiply(v)));            }        }        Vector3D dv = upWithScale.multiply(v);        Vector3D f = new Vector3D(front);        Vector3D dir = dv.add(_dir);        f.normalize();        double alpha;        dir.normalize();        alpha = Math.acos(f.dotProduct(dir));        if ( v > 0 ) alpha *= -1;        // 2. Calculate the plane normal        Matrix4x4 R = new Matrix4x4();        Vector3D n;        R.axisRotation(alpha, left);        n = R.multiply(dv);        n.normalize();        // 3. Build the plane and return        InfinitePlane plane;        plane = new InfinitePlane(n, eyePosition);        return plane;    }    /**    PRE: updateVectors() must be called before this method if camera model    is new or recently changed.    WARNING: This is currently considering only the perspective case!    TODO: The paralel projection case!    */    public InfinitePlane calculateNearPlane()    {        InfinitePlane plane;        Vector3D f = new Vector3D(front);        f.normalize();        Vector3D back = f.multiply(-1);        f = f.multiply(nearPlaneDistance);        Vector3D c = eyePosition.add(f);        plane = new InfinitePlane(back, c);        return plane;    }    /**    PRE: updateVectors() must be called before this method if camera model    is new or recently changed.    WARNING: This is currently considering only the perspective case!    TODO: The paralel projection case!    */    public InfinitePlane calculateFarPlane()    {        InfinitePlane plane;        Vector3D f = new Vector3D(front);        f.normalize();        f = f.multiply(farPlaneDistance);        Vector3D c = eyePosition.add(f);        plane = new InfinitePlane(front, c);        return plane;    }    /**    Given a point in "clipping coordinates space", this method calculates    a six bit opcode, as explained in [FOLE1992].6.5.3, suitable for use in the    Cohen-Suterland line clipping algorithm, taking the input point in    homogeneous space, as noted in [FOLE1992].6.5.4.    Note that the "clipping coodinate space" is the result of transforming    world coordinate space with the composed transform-project matrix for    current camera, as returned by the `calculateProjectionMatrix` method.    Note that in VSDK, the clipping space correspond to the frustum for    the minmax cube from <-1, -1, -1> to <1, 1, 1>.    WARNING: This algoritm FAILS when the point to be tested is in the    plane passing through eye position of the camera and paralel to near     plane! In this case, W gets 0 value, and points are not correctly    classified.    @todo: check this method... currently disabled due to non working cases!    */    private int calculateOutcodeBits(Vector4D p)    {        int bits = 0x00;        if ( p.w > 0 ) {            if ( p.x >  p.w ) bits |= OPCODE_RIGHT;            if ( p.x < -p.w ) bits |= OPCODE_LEFT;            if ( p.y >  p.w ) bits |= OPCODE_UP;            if ( p.y < -p.w ) bits |= OPCODE_DOWN;            if ( p.z >  p.w ) bits |= OPCODE_FAR;            if ( p.z < -p.w ) bits |= OPCODE_NEAR;        }        else {            if ( p.x > -p.w ) bits |= OPCODE_RIGHT;            if ( p.x <  p.w ) bits |= OPCODE_LEFT;            if ( p.y > -p.w ) bits |= OPCODE_UP;            if ( p.y <  p.w ) bits |= OPCODE_DOWN;            if ( p.z > -p.w ) bits |= OPCODE_FAR;            if ( p.z <  p.w ) bits |= OPCODE_NEAR;        }        return bits;    }    private double fpd()    {        return (farPlaneDistance - nearPlaneDistance) / nearPlaneDistance;    }    /**    Given a point in "clipping coordinates space", this method calculates    a six bit opcode, as explained in [FOLE1992].6.5.3, suitable for use in the    Cohen-Suterland line clipping algorithm.    Note that in VSDK, the clipping space correspond to the frustum for    the minmax cube from <-1, -1, -1> to <1, 1, 1>.    WARNING: Currently is only implementing the perspective case!    */    private int calculateOutcodeBits(Vector3D p)    {        int bits = 0x00;        if ( p.z + p.x - 1 > 0 ) bits |= OPCODE_RIGHT;        if ( p.z - p.x - 1 > 0 ) bits |= OPCODE_LEFT;        if ( p.z + p.y - 1 > 0 ) bits |= OPCODE_UP;        if ( p.z - p.y - 1 > 0 ) bits |= OPCODE_DOWN;        // Warning: near plane clipping        if ( p.z > 0 ) bits |= OPCODE_NEAR;        if ( p.z < -fpd() ) bits |= OPCODE_FAR;        return bits;    }    /**    Given a point in world space, this method calculates a six bit opcode,    as explained in [FOLE1992].6.5.3, suitable for use in the Cohen-Suterland    line clipping algorithm. The camera view volume should be represented    by its six bounding planes.    */    private int calculateOutcodeBits(Vector3D p,                                     InfinitePlane right, InfinitePlane left,                                     InfinitePlane up, InfinitePlane down,                                     InfinitePlane far, InfinitePlane near)    {        int bits = 0x00;        if ( right.doContainmentTestHalfSpace(p, VSDK.EPSILON) ==             Geometry.OUTSIDE ) {            bits |= OPCODE_RIGHT;        }        if ( left.doContainmentTestHalfSpace(p, VSDK.EPSILON) ==             Geometry.OUTSIDE ) {            bits |= OPCODE_LEFT;        }        if ( up.doContainmentTestHalfSpace(p, VSDK.EPSILON) ==             Geometry.OUTSIDE) {            bits |= OPCODE_UP;        }        if ( down.doContainmentTestHalfSpace(p, VSDK.EPSILON) ==             Geometry.OUTSIDE ) {            bits |= OPCODE_DOWN;        }        if ( far.doContainmentTestHalfSpace(p, VSDK.EPSILON) ==             Geometry.OUTSIDE ) {            bits |= OPCODE_FAR;        }        if ( near.doContainmentTestHalfSpace(p, VSDK.EPSILON) ==             Geometry.OUTSIDE ) {            bits |= OPCODE_NEAR;        }        return bits;    }    /**    This method implements the Cohen-Sutherland line clipping algorithm with    respect to the view volume defined by current camera. Recieves the two    line endpoints and return true if any part of this line lies inside the    view volume.  In the case the line crosses the view volume, the new    resulting endpoints are calculated and returned.    This algorithm structure follows the one proposed in [FOLE1992].3.12.3,    generalizing it to the 3D case, as noted in [FOLE1992].6.5.3.    */    public boolean clipLineCohenSutherlandPlanes(                             Vector3D point0, Vector3D point1,                             Vector3D clippedPoint0, Vector3D clippedPoint1)    {        //- Local variables definition ------------------------------------        int outcode0;                // 6bit containment code for point0        int outcode1;                // 6bit containment code for point1        int outcodeout;              // Selected endpoint code for iteration        Vector3D clippingMidPoint;   // Selected endpoint clipped for iteration        Ray testRay;                 // Ray use for general line/plane clipping        Vector3D dirFromP0ToP1;      // Temporary for testRay construction        InfinitePlane rightPlane;    // 6 planes defining current camera        InfinitePlane leftPlane;     //   view volume. Note that intersection        InfinitePlane upPlane;       //   tests are done against these planes        InfinitePlane downPlane;     //   using general case non-optimal        InfinitePlane nearPlane;     //   intersections! This sould be        InfinitePlane farPlane;      //   optimized        InfinitePlane clippingPlane; // Selected plane for each iteration        //- Algorithm initial state ---------------------------------------        clippedPoint0.x = point0.x;        clippedPoint0.y = point0.y;        clippedPoint0.z = point0.z;        clippedPoint1.x = point1.x;        clippedPoint1.y = point1.y;        clippedPoint1.z = point1.z;        updateVectors();        clippingMidPoint = new Vector3D();        rightPlane = calculateUPlane(0.5);        leftPlane = calculateUPlane(-0.5);        upPlane = calculateVPlane(0.5);        downPlane = calculateVPlane(-0.5);        nearPlane = calculateNearPlane();        farPlane = calculateFarPlane();        clippingPlane = null;        outcode0 = calculateOutcodeBits(point0, rightPlane, leftPlane,                                       upPlane, downPlane, nearPlane, farPlane);        outcode1 = calculateOutcodeBits(point1, rightPlane, leftPlane,                                      upPlane, downPlane, nearPlane, farPlane);        dirFromP0ToP1 = point1.substract(point0);        dirFromP0ToP1.normalize();        //- Main Cohen-Sutherland iteration cycle (incremental clipping) --        boolean linePasses = false; // Algorithm return value        boolean done = false;       // Iteration exit condition        do {            //- Trivial cases: trivial accept and trivial reject ----------            if ( outcode0 == 0x0 && outcode1 == 0x0 ) {                linePasses = true;                done = true;            }            else if ( (outcode0 & outcode1) != 0x0 ) {                linePasses = false;                done = true;            }            //- Iterative cases: clipping with each of the 6 planes -------            else {                if ( dirFromP0ToP1.length() < VSDK.EPSILON ) {                    // continue;                    return false;                }                //--------------------------------------------------                if ( outcode0 != 0 ) {                    outcodeout = outcode0;                  }                  else {                    outcodeout = outcode1;                }                testRay = new Ray(point0, dirFromP0ToP1);                //--------------------------------------------------                clippingPlane = null;                if ( (OPCODE_UP & outcodeout) != 0x0 ) {                    clippingPlane = upPlane;                }                else if ( (OPCODE_DOWN & outcodeout) != 0x0 ) {                    clippingPlane = downPlane;                }                else if ( (OPCODE_LEFT & outcodeout) != 0x0 ) {                    clippingPlane = leftPlane;                }                else if ( (OPCODE_RIGHT & outcodeout) != 0x0 ) {                    clippingPlane = rightPlane;                }                else if ( (OPCODE_NEAR & outcodeout) != 0x0 ) {                    // Warning: Why test with the contrary plane?                    clippingPlane = farPlane;                }                else if ( (OPCODE_FAR & outcodeout) != 0x0 ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -