Example #1
0
File: vx_util.c Project: DH-std/A3
void vx_util_lookat(double * _eye, double * _lookat, double * _up, double * _out44)
{
    zarray_t * fp = zarray_create(sizeof(matd_t*));

    matd_t * eye = matd_create_data(3,1, _eye);
    zarray_add(fp, &eye);

    matd_t * lookat = matd_create_data(3,1, _lookat);
    zarray_add(fp, &lookat);

    matd_t * up = matd_create_data(3,1, _up);
    zarray_add(fp, &up);

    up = matd_vec_normalize(up);

    zarray_add(fp, &up); // note different pointer than before!

    matd_t * tmp1 = matd_subtract(lookat, eye); zarray_add(fp, &tmp1);

    matd_t * f = matd_vec_normalize(tmp1);      zarray_add(fp, &f);
    matd_t * s = matd_crossproduct(f, up);      zarray_add(fp, &s);
    matd_t * u = matd_crossproduct(s, f);       zarray_add(fp, &u);

    matd_t * M = matd_create(4,4); // set the rows of M with s, u, -f
    zarray_add(fp, &M);
    memcpy(M->data,s->data,3*sizeof(double));
    memcpy(M->data + 4,u->data,3*sizeof(double));
    memcpy(M->data + 8,f->data,3*sizeof(double));
    for (int i = 0; i < 3; i++)
        M->data[2*4 +i] *= -1;
    M->data[3*4 + 3] = 1.0;


    matd_t * T = matd_create(4,4);
    T->data[0*4 + 3] = -eye->data[0];
    T->data[1*4 + 3] = -eye->data[1];
    T->data[2*4 + 3] = -eye->data[2];
    T->data[0*4 + 0] = 1;
    T->data[1*4 + 1] = 1;
    T->data[2*4 + 2] = 1;
    T->data[3*4 + 3] = 1;
    zarray_add(fp, &T);

    matd_t * MT = matd_op("MM",M,T);
    zarray_add(fp, &MT);


    memcpy(_out44, MT->data, 16*sizeof(double));

    // cleanup
    zarray_vmap(fp, matd_destroy);
    zarray_destroy(fp);
}
bool BoundingBox::intersect(BoundingBox *b) {
	double checkL, sum;
	BoundingBox *a = this;
	matd_t *cross;
	matd_t *T = matd_subtract(b->pos, a->pos);

	// Case 1
	checkL = fabs(matd_vec_dot_product(T, a->ux));
	sum = a->hW;
	sum += fabs(b->hW*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hD*matd_vec_dot_product(a->ux, b->uz));

	if (checkL > sum) {
	    //printf("Axis found, case 1\n");
		return false;
	}
	//printf("1 - checkL %f, sum %f\n", checkL, sum);

	// Case 2
	checkL = fabs(matd_vec_dot_product(T, a->uy));
	sum = a->hH;
	sum += fabs(b->hW*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(b->hD*matd_vec_dot_product(a->uy, b->uz));

	if (checkL > sum) {
	    //printf("Axis found, case 2\n");
		return false;
	}
	//printf("2 - checkL %f, sum %f\n", checkL, sum);

	// Case 3
	checkL = fabs(matd_vec_dot_product(T, a->uz));
	sum = a->hD;
	sum += fabs(b->hW*matd_vec_dot_product(a->uz, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(b->hD*matd_vec_dot_product(a->uz, b->uz));

	if (checkL > sum) {
    	//printf("Axis found, case 3\n");
		return false;
	}
	//printf("3 - checkL %f, sum %f\n", checkL, sum);

	// Case 4
	checkL = fabs(matd_vec_dot_product(T, b->ux));
	sum = fabs(a->hW*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(a->hH*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(a->hD*matd_vec_dot_product(a->uz, b->ux));
	sum += b->hW;

	if (checkL > sum) {
	    //printf("Axis found, case 4\n");
		return false;
	}
	//printf("4 - checkL %f, sum %f\n", checkL, sum);

	// Case 5
	checkL = fabs(matd_vec_dot_product(T, b->uy));
	sum = fabs(a->hW*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(a->hH*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(a->hD*matd_vec_dot_product(a->uz, b->uy));
	sum += b->hH;

	if (checkL > sum) {
	    //printf("Axis found, case 5\n");
		return false;
	}
	//printf("5 - checkL %f, sum %f\n", checkL, sum);

	// Case 6
	checkL = fabs(matd_vec_dot_product(T, b->uz));
	sum = fabs(a->hW*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(a->hH*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(a->hD*matd_vec_dot_product(a->uz, b->uz));
	sum += b->hD;
	
	if (checkL > sum) {
	    //printf("Axis found, case 6\n");
		return false;
	}
	//printf("6 - checkL %f, sum %f\n", checkL, sum);

	// Case 7
	cross = matd_crossproduct(a->ux, b->ux);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hH*matd_vec_dot_product(a->uz, b->ux));
	sum += fabs(a->hD*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->ux, b->uy));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 7\n");
		return false;
	}
	//printf("7 - checkL %f, sum %f\n", checkL, sum);

	// Case 8
	cross = matd_crossproduct(a->ux, b->uy);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hH*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(a->hD*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(b->hW*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->ux, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 8\n");
		return false;
	}
	//printf("8 - checkL %f, sum %f\n", checkL, sum);

	// Case 9
	cross = matd_crossproduct(a->ux, b->uz);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hH*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(a->hD*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(b->hW*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hH*matd_vec_dot_product(a->ux, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 9\n");
		return false;
	}
	//printf("9 - checkL %f, sum %f\n", checkL, sum);

	// Case 10
	cross = matd_crossproduct(a->uy, b->ux);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uz, b->ux));
	sum += fabs(a->hD*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uy, b->uy));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 10\n");
		return false;
	}
	//printf("10 - checkL %f, sum %f\n", checkL, sum);

	// Case 11
	cross = matd_crossproduct(a->uy, b->uy);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(a->hD*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hW*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uy, b->ux));
	matd_destroy(cross);
	
	if (checkL > sum) {
	    //printf("Axis found, case 11\n");
		return false;
	}
	//printf("11 - checkL %f, sum %f\n", checkL, sum);

	// Case 12
	cross = matd_crossproduct(a->uy, b->uz);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(a->hD*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hW*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(b->hH*matd_vec_dot_product(a->uy, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 12\n");
		return false;
	}
	//printf("12 - checkL %f, sum %f\n", checkL, sum);

	// Case 13
	cross = matd_crossproduct(a->uz, b->ux);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(a->hH*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uz, b->uy));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 13\n");
		return false;
	}
	//printf("13 - checkL %f, sum %f\n", checkL, sum);

	// Case 14
	cross = matd_crossproduct(a->uz, b->uy);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(a->hH*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hW*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uz, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 14\n");
		return false;
	}
	//printf("14 - checkL %f, sum %f\n", checkL, sum);

	// Case 15
	cross = matd_crossproduct(a->uz, b->uz);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(a->hH*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hW*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(b->hH*matd_vec_dot_product(a->uz, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 15\n");
		return false;
	}
	//printf("15 - checkL %f, sum %f\n", checkL, sum);

	matd_destroy(T);
	return true;
}
Example #3
0
vx_camera_pos_t * default_cam_mgr_get_cam_pos(default_cam_mgr_t * state, int * viewport, uint64_t mtime)
{
    vx_camera_pos_t * p = calloc(1, sizeof(vx_camera_pos_t));
    memcpy(p->viewport, viewport, 4*sizeof(int));

    p->perspective_fovy_degrees = state->perspective_fovy_degrees;
    p->zclip_near = state->zclip_near;
    p->zclip_far = state->zclip_far;

    // process a fit command if necessary:
    if (state->fit != NULL) {
        fit_t * f = state->fit;

        // consume the fit command
        state->fit = NULL; // XXX minor race condition, could lose a fit cmd

        // XXX We can probably do better than this using the viewport...
        state->lookat1[0] = (f->xy0[0] + f->xy1[0]) / 2;
        state->lookat1[1] = (f->xy0[1] + f->xy1[1]) / 2;
        state->lookat1[2] = 0;

        // dimensions of fit
        double Fw = f->xy1[0] - f->xy0[0];
        double Fh = f->xy1[1] - f->xy0[1];

        // aspect ratios
        double Far = Fw / Fh;
        double Var = p->viewport[2] * 1.0 / p->viewport[3];

        double tAngle = tan(p->perspective_fovy_degrees/2*M_PI/180.0);
        double height = fabs(0.5 * (Var > Far ? Fh : Fw / Var) / tAngle);

        state->eye1[0] = state->lookat1[0];
        state->eye1[1] = state->lookat1[1];
        state->eye1[2] = height;

        state->up1[0] = 0;
        state->up1[1] = 1;
        state->up1[2] = 0;

        state->mtime1 = f->mtime;

        free(f);
    }

    if (mtime > state->mtime1) {
        memcpy(p->eye, state->eye1, 3*sizeof(double));
        memcpy(p->up, state->up1, 3*sizeof(double));
        memcpy(p->lookat, state->lookat1, 3*sizeof(double));
        p->perspectiveness = state->perspectiveness1;
    } else  if (mtime <= state->mtime0) {
        memcpy(p->eye, state->eye0, 3*sizeof(double));
        memcpy(p->up, state->up0, 3*sizeof(double));
        memcpy(p->lookat, state->lookat0, 3*sizeof(double));
        p->perspectiveness = state->perspectiveness0;
    } else {
        double alpha1 = ((double) mtime - state->mtime0) / (state->mtime1 - state->mtime0);
        double alpha0 = 1.0 - alpha1;

        scaled_combination(state->eye0,    alpha0, state->eye1,    alpha1, p->eye,    3);
        scaled_combination(state->up0,     alpha0, state->up1,     alpha1, p->up,     3);
        scaled_combination(state->lookat0, alpha0, state->lookat1, alpha1, p->lookat, 3);
        p->perspectiveness = state->perspectiveness0*alpha0 + state->perspectiveness1*alpha1;

        // Tweak so eye-to-lookat is the right distance
        {
            zarray_t * fp = zarray_create(sizeof(matd_t*));

            matd_t * eye = matd_create_data(3,1, p->eye); zarray_add(fp, &eye);
            matd_t * lookat = matd_create_data(3,1, p->lookat); zarray_add(fp, &lookat);
            matd_t * up = matd_create_data(3,1, p->up); zarray_add(fp, &up);

            matd_t * eye0 = matd_create_data(3,1, state->eye0); zarray_add(fp, &eye0);
            matd_t * lookat0 = matd_create_data(3,1, state->lookat0); zarray_add(fp, &lookat0);
            matd_t * up0 = matd_create_data(3,1, state->up0); zarray_add(fp, &up0);

            matd_t * eye1 = matd_create_data(3,1, state->eye1); zarray_add(fp, &eye1);
            matd_t * lookat1 = matd_create_data(3,1, state->lookat1); zarray_add(fp, &lookat1);
            matd_t * up1 = matd_create_data(3,1, state->up1); zarray_add(fp, &up1);


            double dist0 = matd_vec_dist(eye0, lookat0);
            double dist1 = matd_vec_dist(eye1, lookat1);

            matd_t * dist = matd_create_scalar(dist0*alpha0 + dist1*alpha1); zarray_add(fp, &dist);

            matd_t * eye2p = matd_subtract(eye,lookat); zarray_add(fp, &eye2p);
            eye2p = matd_vec_normalize(eye2p); zarray_add(fp, &eye2p);

            eye = matd_op("M + (M*M)", lookat, eye2p, dist);

            // Only modified eye
            memcpy(p->eye, eye->data, 3*sizeof(double));

            zarray_vmap(fp, matd_destroy);

            zarray_destroy(fp);
        }
    }

    // Need to do more fixup depending on interface mode!
    {
        if (state->interface_mode <= 2.0) {
            // stack eye on lookat:
            p->eye[0] = p->lookat[0];
            p->eye[1] = p->lookat[1];
            p->lookat[2] = 0;

            // skip fabs() for ENU/NED compat
            //p->eye[2] = fabs(p->eye[2]);


            {
                matd_t * up = matd_create_data(3,1, p->up);
                up->data[2] = 0; // up should never point in Z
                matd_t * up_norm = matd_vec_normalize(up);

                memcpy(p->up, up_norm->data, sizeof(double)*3);
                matd_destroy(up);
                matd_destroy(up_norm);
            }

        } else if (state->interface_mode == 2.5) {
            zarray_t * fp = zarray_create(sizeof(matd_t*));

            matd_t * eye = matd_create_data(3,1, p->eye); zarray_add(fp, &eye);
            matd_t * lookat = matd_create_data(3,1, p->lookat); zarray_add(fp, &lookat);
            matd_t * up = matd_create_data(3,1, p->up); zarray_add(fp, &up);

            lookat->data[2] = 0.0;

            // Level horizon
            matd_t * dir = matd_subtract(lookat, eye); zarray_add(fp, &dir);
            matd_t * dir_norm = matd_vec_normalize(dir); zarray_add(fp, &dir_norm);
            matd_t * left = matd_crossproduct(up, dir_norm); zarray_add(fp, &left);
            left->data[2] = 0.0;

            left = matd_vec_normalize(left); zarray_add(fp, &left);


            // Don't allow upside down
            //up->data[2] = fmax(0.0, up->data[2]); // XXX NED?

            // Find an 'up' direction perpendicular to left
            matd_t * dot_scalar = matd_create_scalar(matd_vec_dot_product(up, left)); zarray_add(fp, &dot_scalar);
            up = matd_op("M - (M*M)", up,  left, dot_scalar); zarray_add(fp, &up);
            up = matd_vec_normalize(up); zarray_add(fp, &up);

            // Now find eye position by computing new lookat dir
            matd_t * eye_dir = matd_crossproduct(up, left); zarray_add(fp, &eye_dir);

            matd_t *eye_dist_scalar = matd_create_scalar(matd_vec_dist(eye, lookat)); zarray_add(fp, &eye_dist_scalar);

            eye = matd_op("M + (M*M)", lookat, eye_dir, eye_dist_scalar); zarray_add(fp, &eye);

            // export results back to p:
            memcpy(p->eye, eye->data, sizeof(double)*3);
            memcpy(p->lookat, lookat->data, sizeof(double)*3);
            memcpy(p->up, up->data, sizeof(double)*3);

            zarray_vmap(fp, matd_destroy);
            zarray_destroy(fp);
        }
    }

    // Fix up for bad zoom
    if (1) {
        matd_t * eye = matd_create_data(3,1, p->eye);
        matd_t * lookat = matd_create_data(3,1, p->lookat);
        matd_t * up = matd_create_data(3,1, p->up);

        matd_t * lookeye = matd_subtract(lookat, eye);
        matd_t * lookdir = matd_vec_normalize(lookeye);
        double dist =  matd_vec_dist(eye, lookat);
        dist  = fmin(state->zclip_far / 3.0, dist);
        dist  = fmax(state->zclip_near * 3.0, dist);

        matd_scale_inplace(lookdir, dist);

        matd_t * eye_fixed = matd_subtract(lookat, lookdir);

        memcpy(p->eye, eye_fixed->data, sizeof(double)*3);

        matd_destroy(eye);
        matd_destroy(lookat);
        matd_destroy(up);
        matd_destroy(lookeye);
        matd_destroy(lookdir);
        matd_destroy(eye_fixed);
    }

    // copy the result back into 'state'
    {
        memcpy(state->eye0, p->eye, 3*sizeof(double));
        memcpy(state->up0, p->up, 3*sizeof(double));
        memcpy(state->lookat0, p->lookat, 3*sizeof(double));
        state->perspectiveness0 = p->perspectiveness;
        state->mtime0 = mtime;
    }

    return p;
}
void body_getServoAngles(Body *body, double servoAngles[], bool right_side) {
	matd_t* floor_shoulder;
	matd_t* shoulder_elbow;
	matd_t* shoulder_elbow0;
	matd_t* shoulder_elbow1;
	matd_t* elbow_wrist;
	joint_t shoulder, elbow, wrist;

	if(right_side){
		//use right side of body
		shoulder = body->getJoint(RSHOULDER);
		elbow = body->getJoint(RELBOW);
		wrist = body->getJoint(RWRIST);
	}else{
		//use left side of body
		shoulder = body->getJoint(LSHOULDER);
		elbow = body->getJoint(LELBOW);
		wrist = body->getJoint(LWRIST);
	}

	double floor_shoulder_data[3] = {
		0, shoulder.y, 0};

	double shoulder_elbow_data[3] = {
		elbow.x - shoulder.x,
		elbow.y - shoulder.y,
		elbow.z - shoulder.z};

	//Shoulder rotation in the yz plane (forward/backward)
	double shoulder_elbow_data0[3] = {
		0,
		elbow.y - shoulder.y,
		elbow.z - shoulder.z}; 

	//Shoulder rotation in the xy plane (left/right)
	double shoulder_elbow_data1[3] = {
		elbow.x - shoulder.x,
		elbow.y - shoulder.y,
		0};

	double elbow_wrist_data[3] = {
		wrist.x - elbow.x,
		wrist.y - elbow.y,
		wrist.z - elbow.z};

	floor_shoulder = matd_create_data(3, 1, floor_shoulder_data);
	shoulder_elbow = matd_create_data(3, 1, shoulder_elbow_data);
	//shoulder_elbow0 = matd_create_data(3, 1, shoulder_elbow_data0);
	shoulder_elbow1 = matd_create_data(3, 1, shoulder_elbow_data1);
	elbow_wrist = matd_create_data(3, 1, elbow_wrist_data);

	double magfs = matd_vec_mag(floor_shoulder);
	double magse = matd_vec_mag(shoulder_elbow);
	//double magse0 = matd_vec_mag(shoulder_elbow0);
	double magse1 = matd_vec_mag(shoulder_elbow1);
	double magew = matd_vec_mag(elbow_wrist);
	
	//double shoulderValue0 = matd_vec_dot_product(floor_shoulder, shoulder_elbow0) / (magfs * magse0);
	double shoulderValue1 = matd_vec_dot_product(floor_shoulder, shoulder_elbow1) / (magfs * magse1);
	double elbowValue = matd_vec_dot_product(shoulder_elbow, elbow_wrist) / (magse * magew);

	//printf("Elbow: %g\n", elbowValue);

	//double shoulderAngle0 = (acos(shoulderValue0));
	double shoulderAngle1 = sgn(elbow.y - shoulder.y)*(acos(shoulderValue1) - M_PI/2);
	double elbowAngle = acos(elbowValue);

	/*if (elbow.z - shoulder.z < 0) {
		shoulderAngle0 = M_PI - shoulderAngle0;
	} else {
		shoulderAngle0 = shoulderAngle0 - M_PI;
	}*/

	if (elbow.y < shoulder.y) {
		shoulderAngle1 = -shoulderAngle1;
	}

	double unitZ_data[3] = {0, 0, 1};
	matd_t *unitZ = matd_create_data(3, 1, unitZ_data);
	matd_t *elbowCheck = matd_crossproduct(elbow_wrist, shoulder_elbow);
	double elbowSign = sgn(matd_vec_dot_product(elbowCheck, unitZ));

	matd_destroy(unitZ);
	matd_destroy(elbowCheck);

	servoAngles[1] = shoulderAngle1;
	servoAngles[2] = elbowSign*elbowAngle;

	//printf("shoulder - %f, elbow - %f\n", servoAngles[1], servoAngles[2]);

	matd_destroy(floor_shoulder);
	matd_destroy(shoulder_elbow);
	//matd_destroy(shoulder_elbow0);
	matd_destroy(shoulder_elbow1);
	matd_destroy(elbow_wrist);
}