pastebin

Paste #BmC -- näytä pelkkänä tekstinä -- uusi tämän pohjalta

Värjäys: Tyyli: ensimmäinen rivinumero: Tabin korvaus:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
void inventorycube(video::IImage *top, video::IImage *left,
		video::IImage *right, video::IImage *dst)
{
	TimeTaker timetaker("inventorycube");
	if(top == NULL || left == NULL || right == NULL || dst == NULL)
		return;
	
	core::dimension2d<u32> topdim = top->getDimension();
	core::dimension2d<u32> leftdim = left->getDimension();
	core::dimension2d<u32> rightdim = right->getDimension();
	core::dimension2d<u32> dstdim = dst->getDimension();

	assert(dst->getColorFormat() == video::ECF_A8R8G8B8);

	u32 *data = (u32*) dst->lock();
	if(data == NULL)
		return;

	u32 w = dstdim.Width;
	u32 h = dstdim.Height;

	// Set destination image to fully transparent
	memset(data, 0, w*h*sizeof(u32));

	// Calculate projection-to-view transformation
	// (orthogonal, left-handed)

	f32 pw = 1.65;  // width of view volume
	f32 ph = 1.65;  // height of view volume
	v2f pscale(pw / w, -ph / h);
	v2f ptrans(-pw / 2, ph / 2);

	// Calculate view-to-world transformation (left-handed)

	v3f position(0, 1.0, -1.5);  // camera position
	position.rotateXZBy(45);     // ^
	v3f target(0, 0, 0);         // camera look-at point
	v3f upVector(0, 1, 0);       // camera up vector

	v3f zaxis = target - position;
	zaxis.normalize();

	v3f xaxis = upVector.crossProduct(zaxis);
	xaxis.normalize();

	v3f yaxis = zaxis.crossProduct(xaxis);

	// Calculate projection-to-world transformation

	core::matrix4 pt;  // (part of a) matrix

	pt[0]  = pscale.X*xaxis.X;
	pt[1]  = pscale.X*xaxis.Y;
	pt[2]  = pscale.X*xaxis.Z;

	pt[4]  = pscale.Y*yaxis.X;
	pt[5]  = pscale.Y*yaxis.Y;
	pt[6]  = pscale.Y*yaxis.Z;

	pt[8]  = zaxis.X;
	pt[9]  = zaxis.Y;
	pt[10] = zaxis.Z;

	pt[12] = ptrans.X * xaxis.X + ptrans.Y * yaxis.X + position.X;
	pt[13] = ptrans.X * xaxis.Y + ptrans.Y * yaxis.Y + position.Y;
	pt[14] = ptrans.X * xaxis.Z + ptrans.Y * yaxis.Z + position.Z;

	// Calculate coefficients needed to calculate pz
	// (z in projection space)
	// This works because the shape of the unit cube is known

	assert(fabs(pt[8]) > 1e-6);
	assert(fabs(pt[9]) > 1e-6);
	assert(fabs(pt[10]) > 1e-6);

	// world coordinates: (wx, wy, wz)
	// top face: wy = 0.5
	v3f pzcoeff_top = v3f(-pt[1], -pt[5], 0.5 - pt[13]) / pt[9];
	// left face: wz = -0.5
	v3f pzcoeff_left = v3f(-pt[2], -pt[6], -0.5 - pt[14]) / pt[10];
	// right face: wx = 0.5
	v3f pzcoeff_right = v3f(-pt[0], -pt[4], 0.5 - pt[12]) / pt[8];


	u32 *ptr = data;

	for(u32 py = 0; py < h; ++py)
	for(u32 px = 0; px < w; ++px)
	{
		v3f projectionPos(px, py, 1);
		f32 pz, wx, wy, wz;

		pz = projectionPos.dotProduct(pzcoeff_top);
		wx = px*pt[0] + py*pt[4] + pz*pt[8] + pt[12];
		wz = px*pt[2] + py*pt[6] + pz*pt[10] + pt[14];
		if(wx*wx < 0.25 && wz*wz < 0.25){ // |wx|, |wz| < 0.5?
			s32 top_px = topdim.Width  * (wx+0.5);
			s32 top_py = topdim.Height * (wz+0.5);
			video::SColor pixel = top->getPixel(top_px, top_py);
			*ptr++ = pixel.color;
			continue;
		}

		pz = projectionPos.dotProduct(pzcoeff_left);
		wx = px*pt[0] + py*pt[4] + pz*pt[8] + pt[12];
		wy = px*pt[1] + py*pt[5] + pz*pt[9] + pt[13];
		if(wx*wx < 0.25 && wy*wy < 0.25){ // |wx|, |wy| < 0.5?
			s32 left_px = leftdim.Width  * (wx+0.5);
			s32 left_py = leftdim.Height * (wy+0.5);
			video::SColor pixel = left->getPixel(left_px, left_py);
			*ptr++ = pixel.color;
			continue;
		}

		pz = projectionPos.dotProduct(pzcoeff_right);
		wy = px*pt[1] + py*pt[5] + pz*pt[9] + pt[13];
		wz = px*pt[2] + py*pt[6] + pz*pt[10] + pt[14];
		if(wy*wy < 0.25 && wz*wz < 0.25){ // |wy|, |wz| < 0.5?
			s32 right_px = rightdim.Width  * (wy+0.5);
			s32 right_py = rightdim.Height * (wz+0.5);
			video::SColor pixel = right->getPixel(right_px, right_py);
			*ptr++ = pixel.color;
			continue;
		}

		ptr++;
	}

	timetaker.stop();
}