Skip to content
Snippets Groups Projects
Select Git revision
  • 90bb8a1f787f49149efe173c3bf4552b482ef3e8
  • master default protected
  • removing_internal_representations
3 results

Server.java

Blame
  • rasterize.c 9.83 KiB
    #include "rasterize.h"
    
    inline float removeSign(float f){
        if(f<0)
            return 0;
        return f;
    }
    
    _2x1Matrix transpose_map(_3x3Matrix m1, _3x1Matrix m2){
        _2x1Matrix ma = {
                (m1.a11 * m2.a11) + (m1.a12 * m2.a21) + (m1.a13 * m2.a31),
                (m1.a21 * m2.a11) + (m1.a22 * m2.a21) + (m1.a23 * m2.a31),
        };
    
        return ma;
    }
    
    rectangle getXYBound2d(tri2d t){
        uint16_t xHigh = (uint16_t)fmax(fmax(t.p0.a11,t.p1.a11),t.p2.a11);
        uint16_t xLow = (uint16_t)fmin(fmin(t.p0.a11,t.p1.a11),t.p2.a11);
        uint16_t yHigh = (uint16_t)fmax(fmax(t.p0.a21,t.p1.a21),t.p2.a21);
        uint16_t yLow = (uint16_t)fmin(fmin(t.p0.a21,t.p1.a21),t.p2.a21);
    
        rectangle r = {xLow, xHigh+1, yLow, yHigh+1};
        return r;
    }
    
    rectangle getXYBound2dRect(rect2d t){
        uint16_t xLow = (uint16_t)fmin(fmin(fmin(removeSign(t.p0.a11),removeSign(t.p1.a11)),
                                            removeSign(t.p2.a11)),removeSign(t.p3.a11));
        uint16_t xHigh = (uint16_t)fmax(fmax(fmax(removeSign(t.p0.a11),removeSign(t.p1.a11)),
                                             removeSign(t.p2.a11)),removeSign(t.p3.a11));
        uint16_t yLow = (uint16_t)fmin(fmin(fmin(removeSign(t.p0.a21),removeSign(t.p1.a21)),
                                            removeSign(t.p2.a21)),removeSign(t.p3.a21));
        uint16_t yHigh = (uint16_t)fmax(fmax(fmax(removeSign(t.p0.a21),removeSign(t.p1.a21)),
                                             removeSign(t.p2.a21)),removeSign(t.p3.a21));
    
        rectangle r = {xLow, xHigh+1, yLow, yHigh+1};
        return r;
    }
    
    rectangle getXYBound3d(tri3d t){
        uint16_t xHigh = (uint16_t)fmax(fmax(removeSign(t.p0.a11),removeSign(t.p1.a11)),removeSign(t.p2.a11));
        uint16_t xLow = (uint16_t)fmin(fmin(removeSign(t.p0.a11),removeSign(t.p1.a11)),removeSign(t.p2.a11));
        uint16_t yHigh = (uint16_t)fmax(fmax(removeSign(t.p0.a21),removeSign(t.p1.a21)),removeSign(t.p2.a21));
        uint16_t yLow = (uint16_t)fmin(fmin(removeSign(t.p0.a21),removeSign(t.p1.a21)),removeSign(t.p2.a21));
    
        rectangle r = {xLow, xHigh+1, yLow, yHigh+1};
        return r;
    }
    
    void affineRasterize(_2x2Matrix m, PGM_P imgdata, rectangle imgRegion, int16_t dispX, int16_t dispY){ //Rectangle affine without Composites
        rect2d t = {{imgRegion.left, imgRegion.top}, {imgRegion.right, imgRegion.top},
                    {imgRegion.right, imgRegion.bottom}, {imgRegion.left, imgRegion.bottom}};
        _2x2Matrix invM = inverse_2x2(m);
        rect2d tP = transpose2dRect(t, m);
    
        rectangle r = getXYBound2dRect(tP);
        r.bottom = removeSign((((int16_t) r.bottom) + dispY));
        r.right = removeSign((((int16_t) r.right) + dispX));
    
        uint16_t imgwidth = imgRegion.right-imgRegion.left;
        uint16_t imgheight = imgRegion.bottom-imgRegion.top;
        rectangleInRegion(&r);
        int16_t width = r.right - r.left;
        int16_t height = r.bottom - r.top;
    
        char* targetptr = imgdata;
        setupDraw(r);
        uint16_t pixVal;
    
        for(int16_t y=-dispY; y<=height-dispY; y++)
            for(int16_t x=-dispX; x<=width-dispX; x++){
                _2x1Matrix p = {x,y};
                _2x1Matrix pT = transpose_2x2(invM, p);
                if(pT.a11 >= 0 && pT.a11 <= imgwidth
                && pT.a21 >= 0 && pT.a21 <= imgheight){
                    uint16_t xComp = (uint16_t) (removeSign(pT.a11));
                    uint16_t yComp = (uint16_t) (removeSign(pT.a21));
                    targetptr = imgdata + (2*(xComp+(yComp*(imgwidth+1))));
                    pixVal = pgm_read_word(targetptr);
                } else {
                    pixVal = 12;
                }
                write_data16(pixVal);
            }
    }
    
    void perspectiveRasterize(tri3d t, tri2d tuv, PGM_P imgdata, rectangle imgRegion) {
        _3x3Matrix triangleMat = combine(t.p0, t.p1, t.p2);
        _3x3Matrix uvMat = combine2d(tuv.p0, tuv.p1, tuv.p2);
        _3x3Matrix invMTM = inverse_3x3(triangleMat);
        _3x3Matrix mapping = multiply_3x3(uvMat, invMTM);
        plane3d pl = getPlane(t);
    
        rectangle r = getXYBound3d(t);
        uint16_t imgwidth = imgRegion.right-imgRegion.left;
        uint16_t imgheight = imgRegion.bottom-imgRegion.top;
        rectangleInRegion(&r);
        uint16_t width = r.right - r.left;
        uint16_t height = r.bottom - r.top;
    
        tri2d t2d = {{t.p0.a11,t.p0.a21},
                     {t.p1.a11,t.p1.a21},
                     {t.p2.a11,t.p2.a21}};
    
        char* targetptr = imgdata;
        setupDraw(r);
        uint16_t pixVal;
    
        for (uint16_t y = r.top; y <= r.bottom; y++) {
            for (uint16_t x = r.left; x <= r.right; x++) {
                _2x1Matrix point = {x, y};
                _2x1Matrix tPoint = transpose_2x3(mapping, point);
                if(inTriangle(tPoint.a11, tPoint.a21, tuv)){
                    uint16_t xComp = (uint16_t) (removeSign(tPoint.a11));
                    uint16_t yComp = (uint16_t) (removeSign(tPoint.a21));
                    targetptr = imgdata + (2*(xComp+(yComp*(imgwidth+1))));
                    pixVal = pgm_read_word(targetptr);
                } else {
                    pixVal = 12;
                }
                write_data16(pixVal);
            }
        }
    }
    
    void perspectiveRasterizeComposite(tri3d t, tri2d tuv, PGM_P imgdata, rectangle imgRegion, float composite){
        _3x3Matrix triangleMat = combine(t.p0, t.p1, t.p2);
        _3x3Matrix uvMat = combine2d(tuv.p0, tuv.p1, tuv.p2);
        _3x3Matrix invMTM = inverse_3x3(triangleMat);
        _3x3Matrix mapping = multiply_3x3(uvMat, invMTM);
        plane3d pl = getPlane(t);
    
        rectangle r = getXYBound3d(t);
        uint16_t imgwidth = imgRegion.right-imgRegion.left;
        uint16_t imgheight = imgRegion.bottom-imgRegion.top;
        rectangleInRegion(&r);
        uint16_t width = r.right - r.left;
        uint16_t height = r.bottom - r.top;
    
        tri2d t2d = {{t.p0.a11,t.p0.a21},
                     {t.p1.a11,t.p1.a21},
                     {t.p2.a11,t.p2.a21}};
    
        char* targetptr = imgdata;
        uint16_t pixVal;
    
        if(composite <= 0 || composite > 1.0f)
            return;
    
        for (uint16_t y = 0; y <= r.bottom-r.top; y++) {
            uint16_t yVal = y + r.top;
            rectangle rReg;
            uint16_t topR = y + r.top;
    
            write_cmd(COLUMN_ADDRESS_SET);
            write_data16(r.left);
            write_data16(r.right);
            write_cmd(PAGE_ADDRESS_SET);
            write_data16(topR);
            write_data16(topR);
            write_cmd(MEMORY_READ);
    
            uint16_t colorValues[width + 1];
            read_data(); //Throw away a byte
            for (uint16_t x = 0; x <= r.right-r.left; x++) {
                unsigned char r = read_data() >> 2;
                unsigned char g = read_data() >> 2;
                unsigned char b = read_data() >> 2;
                uint16_t value = (((uint16_t)b)>>1) + (((uint16_t)g) << 5) + ((((uint16_t)r)>>1) << 11);
                colorValues[x] = value; //It'd be quick to not convert but requires bigger cache, makes this less memory heavy
            }
    
            write_cmd(MEMORY_WRITE);
            for (uint16_t x = 0; x <= r.right-r.left; x++) {
                uint16_t xVal = x + r.left;
                _2x1Matrix point = {xVal, yVal};
                _2x1Matrix tPoint = transpose_2x3(mapping, point);
                if(inTriangle(tPoint.a11, tPoint.a21, tuv)){
                    uint16_t xComp = (uint16_t) (removeSign(tPoint.a11));
                    uint16_t yComp = (uint16_t) (removeSign(tPoint.a21));
                    targetptr = imgdata + (2*(xComp+(yComp*(imgwidth+1))));
                    pixVal = pgm_read_word(targetptr);
                    if(composite != 1.0f){
                        unsigned char r = ((unsigned char) ((((colorValues[x]>>11) & 31) * (1.0 - composite)) + (((pixVal>>11) & 31) * (composite)))) & 31;
                        unsigned char g = ((unsigned char) ((((colorValues[x]>>5) & 63) * (1.0 - composite)) + (((pixVal>>5) & 63) * (composite)))) & 63;
                        unsigned char b = ((unsigned char) (((colorValues[x] & 31) * (1.0 - composite)) + ((pixVal & 31) * (composite)))) & 31;
                        pixVal = ((uint16_t)b) + (((uint16_t)g) << 5) + ((((uint16_t)r)) << 11);
                    }
    
                } else {
                    pixVal = colorValues[x];
                }
                write_data16(pixVal);
            }
        }
    }
    
    //Credit:Kornel Kisielewicz, https://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle
    
    float triSign (_2x1Matrix p0, _2x1Matrix p1, _2x1Matrix p2){
        return ((p0.a11 - p2.a11) * (p1.a21 - p2.a21)) -  ((p1.a11 - p2.a11) * (p0.a21 - p2.a21));
    }
    
    plane3d getPlane(tri3d t){
        _3x1Matrix Vp2p0 = minus_3x1(t.p2, t.p0);
        _3x1Matrix Vp1p0 = minus_3x1(t.p1, t.p0);
        _3x1Matrix crossVectors = crossProduct(Vp1p0,Vp2p0);
        plane3d p = {crossVectors, t.p0};
    
        return p;
    }
    
    float getZ(float x, float y, plane3d p){
        float z = p.anchor.a31 + ((-(p.gr.a11*(x-p.anchor.a11))-(p.gr.a21*(y-p.anchor.a21)))/p.gr.a31);
        return z;
    }
    
    unsigned char inTriangle(float x, float y, tri2d t){
        _2x1Matrix px = {x, y};
        float d1 = triSign(px, t.p0, t.p1);
        float d2 = triSign(px, t.p1, t.p2);
        float d3 = triSign(px, t.p2, t.p0);
    
        unsigned char hasNegative = (d1 < 0) || (d2 < 0) || (d3 < 0);
        unsigned char hasPositive = (d1 > 0) || (d2 > 0) || (d3 > 0);
    
        return !(hasNegative && hasPositive);
    }
    
    
    rect2d transpose2dRect(rect2d t, _2x2Matrix m){
        rect2d tP;
        tP.p0 = transpose_2x2(m, t.p0);
        tP.p1 = transpose_2x2(m, t.p1);
        tP.p2 = transpose_2x2(m, t.p2);
        tP.p3 = transpose_2x2(m, t.p3);
    
        return tP;
    }
    
    tri3d seperate(_3x3Matrix m){
        _3x1Matrix p0 = {m.a11, m.a21, m.a31};
        _3x1Matrix p1 = {m.a12, m.a22, m.a32};
        _3x1Matrix p2 = {m.a13, m.a23, m.a33};
    
        tri3d t = {p0, p1, p2};
        return t;
    }
    
    tri3d transpose3dTri(tri3d t, _3x3Matrix m) {
        _3x3Matrix m1 = combine(t.p0, t.p1, t.p2);
        _3x3Matrix tP = multiply_3x3(m, m1);
        return seperate(tP);
    }
    
    _3x3Matrix combine2d(_2x1Matrix m1, _2x1Matrix m2, _2x1Matrix m3){
        _3x3Matrix m = {m1.a11, m2.a11, m3.a11,
                        m1.a21, m2.a21, m3.a21,
                        0, 0, 0};
        return m;
    }
    
    _2x1Matrix transpose_2x3(_3x3Matrix m1, _2x1Matrix m2){
        _2x1Matrix ma = {
                (m1.a11 * m2.a11) + (m1.a12 * m2.a21) + m1.a13,
                (m1.a21 * m2.a11) + (m1.a22 * m2.a21) + m1.a23,
    
        };
        return ma;
    }