


/* Feel free to read this struct's members. Feel free to alter the contents of 
the isometry and the shape data. */
typedef struct bodyBody bodyBody;
struct bodyBody {
    isoIsometry isometry;
    int shapeDataSize;
    void *shapeData;
    /* Given a body with the specified modeling isometry and shape data. Given a 
    ray x(t) = p + t * u in world coordinates. Outputs the ray's intersection 
    with the body. */
    void (*getIntersection)(
        const isoIsometry *isom, const void *shapeData, const double p[3], 
        const double u[3], rayIntersection *inter);
};

/* Initializes the body, returning an error code (0 on success). On success, 
don't forget to bodyFinalize when you're done. The isometry is initialized to 
the trivial isometry. The uniforms are not set. */
int bodyInitialize(
        bodyBody *body, int shapeDataSize, 
        void (*getIntersection)(
        	const isoIsometry *isom, const void *shapeData, const double p[3], 
        	const double u[3], rayIntersection* inter)) {
    if (shapeDataSize > 0) {
		body->shapeData = malloc(shapeDataSize);
		if (body->shapeData == NULL) {
			fprintf(stderr, "error: bodyInitialize: malloc failed\n");
			return 1;
		}
    }
    body->shapeDataSize = shapeDataSize;
    body->getIntersection = getIntersection;
    double transl[3] = {0.0, 0.0, 0.0};
    isoSetTranslation(&(body->isometry), transl);
    double rot[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}};
    isoSetRotation(&(body->isometry), rot);
    return 0;
}

/* Releases the resources backing the body. */
void bodyFinalize(bodyBody *body) {
	if (body->shapeDataSize > 0)
		free(body->shapeData);
}

/* Using the body's shape, outputs the appropriate rayIntersection. */
void bodyGetIntersection(
        const bodyBody *body, const double p[3], const double u[3], 
        rayIntersection* inter) {
    body->getIntersection(&(body->isometry), body->shapeData, p, u, inter);
}


