All pastes #945379 Raw Edit

Something

public text v1 · immutable
·published 2008-03-16 21:53 UTC
rendered paste body
#include <iostream>
#include <math.h>
#include "tinyptc.h"

#define WIDTH 640
#define HEIGHT 480
#define SIZE WIDTH*HEIGHT

#define WORLDYMIN -1.0f
#define WORLDYMAX 1.0f

#define WORLDXMIN -1.333f
#define WORLDXMAX 1.333f

int pixel[SIZE];


typedef struct {
	float x;
	float y;
	float z;
} float3;

typedef struct {
	float3 coordinates;
	float radius;
	float3 color;
} sphere;

float screentoworld(int smin, int smax, int s, float wmin, float wmax);
float3 iraysphere(float3& s, float& r, float3& p0, float3& p1);
float discriminant(float3& f);
float irayspherelight(float3& s, float& r, float3& p0, float3& p1);

int main(int argc, char * argv[])
{
	if (!ptc_open("test", WIDTH, HEIGHT)) {
		return 1;
	}

	int x;
	int y;

	float3 camera;
	camera.x = 0.0f;
	camera.y = 0.0f;
	camera.z = -10.0f;

	sphere s1;
	s1.coordinates.x = 0.0f;
	s1.coordinates.y = 0.0f;
	s1.coordinates.z = 0.0f;
	s1.radius = 0.5f; 
	s1.color.x = 1.0f;
	s1.color.y = 1.0f;
	s1.color.z = 0.0f;


	for (y = 0; y < HEIGHT; y++) {
		for (x = 0; x < WIDTH; x++) {
			float3 pix;

			pix.x = screentoworld(0, WIDTH, x, WORLDXMIN, WORLDXMAX);
			pix.y = screentoworld(0, HEIGHT, y, WORLDYMIN, WORLDYMAX);
			pix.z = 0;

			float hit = discriminant(iraysphere(s1.coordinates, s1.radius, camera, pix));

			if(hit >= 0) {
				float kd = 0.9f;
				float ka = 0.1f;
				float f = irayspherelight(s1.coordinates, s1.radius, camera, pix);

				float r = (kd * f * s1.color.x) + (ka * s1.color.x);
				float g = (kd * f * s1.color.y) + (ka * s1.color.y);
				float b = (kd * f * s1.color.z) + (ka * s1.color.z);

				pixel[y * WIDTH + x] = ((int)(r * 255.0f) << 16) | ((int)(g * 255.0f) << 8) | (int)(b * 255.0f);
			} else {
				pixel[y * WIDTH + x] = (0xCC << 16) | (0xCC << 8) | 0xCC;
			}

			//std::cout << "Hit = " << hit << "\n";

		}
		ptc_update(pixel);
	}

	while (true) {
		ptc_update(pixel);
	}
}

float screentoworld(int smin, int smax, int s, float wmin, float wmax) {
	return (((wmax - wmin) * ((float)s / ((float)smax - (float)smin))) + wmin);
}

float3 iraysphere(float3& s, float& r, float3& p0, float3& p1) {
	//std::cout << "p0.x = " << p0.x << " p0.y = " << p0.y << " p0.z = " << p0.z << "\n";
	//std::cout << "p1.x = " << p1.x << " p1.y = " << p1.y << " p1.z = " << p1.z << "\n";	
	
	float dx = p1.x - p0.x;
	float dy = p1.y - p0.y;
	float dz = p1.z - p0.z;

	float3 ret;

	ret.x = (dx * dx) + (dy * dy) + (dz * dz);
	ret.y = (2 * dx * (p0.x - s.x)) + (2 * dy * (p0.y - s.y)) + (2.0f * dz * (p0.z - s.z));
	ret.z = (s.x * s.x) + (s.y * s.y) + (s.z * s.z) + 
	          (p0.x * p0.x) + (p0.y * p0.y) + (p0.z * p0.z) -
			  (2.0f * ((s.x * p0.x) + (s.y * p0.y) + (s.y * p0.z))) -
			  (r * r);

	return ret;
}

float irayspherelight(float3& s, float& r, float3& p0, float3& p1) {
	//std::cout << "p0.x = " << p0.x << " p0.y = " << p0.y << " p0.z = " << p0.z << "\n";
	//std::cout << "p1.x = " << p1.x << " p1.y = " << p1.y << " p1.z = " << p1.z << "\n";	
	
	float dx = p1.x - p0.x;
	float dy = p1.y - p0.y;
	float dz = p1.z - p0.z;

	float a = (dx * dx) + (dy * dy) + (dz * dz);
	float b = (2 * dx * (p0.x - s.x)) + (2 * dy * (p0.y - s.y)) + (2.0f * dz * (p0.z - s.z));
	float c = (s.x * s.x) + (s.y * s.y) + (s.z * s.z) + 
	          (p0.x * p0.x) + (p0.y * p0.y) + (p0.z * p0.z) -
			  (2.0f * ((s.x * p0.x) + (s.y * p0.y) + (s.y * p0.z))) -
			  (r * r);

	float d = ((b * b) - (4.0f * a * c));
	float t = ((-b - sqrt(d)) / (2.0f * a));

	float x = p0.x + (t * dx);
	float y = p0.y + (t * dy);
	float z = p0.z + (t * dz);

	float3 n;
	n.x = ((x - s.x) / r);
	n.y = ((y - s.y) / r);
	n.z = ((z - s.z) / r);

	float3 lprime;
	lprime.x = (-1.0f - x);
	lprime.y = (1.0f - y);
	lprime.z = (0.0f - z);

	float3 l;
	l.x = (lprime.x / abs(lprime.x));
	l.y = (lprime.y / abs(lprime.y));
	l.z = (lprime.z / abs(lprime.z));

	float factor = ((l.x * n.x) + (l.y * n.y) + (l.z * n.z));

	return factor;
}

float discriminant(float3& f) {
	return ((f.y * f.y) - (4.0f * f.x * f.z));
}