void rebuildMatrices() { if (!needsRebuild) { return; } needsRebuild = false; warp_Vector forward, up, right; forward = warp_Vector.sub(lookat, pos); if (Math.Abs(forward.x) < 0.001f && Math.Abs(forward.z) < 0.001f) { right = new warp_Vector(1f, 0f, 0f); if (forward.y < 0) { up = new warp_Vector(0f, 0f, 1f); } else { up = new warp_Vector(0f, 0f, -1f); } } else { up = new warp_Vector(0f, 1f, 0f); right = warp_Vector.getNormal(up, forward); up = warp_Vector.getNormal(forward, right); } forward.normalize(); normalmatrix = new warp_Matrix(right, up, forward); if (rollfactor != 0) { normalmatrix.rotate(0, 0, rollfactor); } matrix = normalmatrix.getClone(); matrix.shift(pos.x, pos.y, pos.z); matrix = matrix.inverse(); normalmatrix = normalmatrix.inverse(); if (isOrthographic) { projmatrix.m00 = screenwidth / orthoViewWidth; projmatrix.m03 = halfscreenwidth; projmatrix.m11 = -screenheight / orthoViewHeight; projmatrix.m13 = halfscreenheight; projmatrix.m22 = 1.0f; } else { float screenscale = (screenwidth < screenheight) ? screenwidth : screenheight; projmatrix.m00 = screenscale / fovfact; projmatrix.m03 = 0; projmatrix.m11 = -screenscale / fovfact; projmatrix.m13 = 0; projmatrix.m22 = 1.0f; } matrix = warp_Matrix.multiply(projmatrix, matrix); }
public static warp_Matrix quaternionMatrix(warp_Quaternion quat) { warp_Matrix m = new warp_Matrix(); float xx = quat.X * quat.X; float xy = quat.X * quat.Y; float xz = quat.X * quat.Z; float xw = quat.X * quat.W; float yy = quat.Y * quat.Y; float yz = quat.Y * quat.Z; float yw = quat.Y * quat.W; float zz = quat.Z * quat.Z; float zw = quat.Z * quat.W; m.m00 = 1 - 2 * (yy + zz); m.m01 = 2 * (xy - zw); m.m02 = 2 * (xz + yw); m.m10 = 2 * (xy + zw); m.m11 = 1 - 2 * (xx + zz); m.m12 = 2 * (yz - xw); m.m20 = 2 * (xz - yw); m.m21 = 2 * (yz + xw); m.m22 = 1 - 2 * (xx + yy); m.m03 = m.m13 = m.m23 = m.m30 = m.m31 = m.m32 = 0; m.m33 = 1; return(m); }
public warp_Matrix inverse() { warp_Matrix m = new warp_Matrix(); float q1 = m12; float q6 = m10 * m01; float q7 = m10 * m21; float q8 = m02; float q13 = m20 * m01; float q14 = m20 * m11; float q21 = m02 * m21; float q22 = m03 * m21; float q25 = m01 * m12; float q26 = m01 * m13; float q27 = m02 * m11; float q28 = m03 * m11; float q29 = m10 * m22; float q30 = m10 * m23; float q31 = m20 * m12; float q32 = m20 * m13; float q35 = m00 * m22; float q36 = m00 * m23; float q37 = m20 * m02; float q38 = m20 * m03; float q41 = m00 * m12; float q42 = m00 * m13; float q43 = m10 * m02; float q44 = m10 * m03; float q45 = m00 * m11; float q48 = m00 * m21; float q49 = q45 * m22 - q48 * q1 - q6 * m22 + q7 * q8; float q50 = q13 * q1 - q14 * q8; float q51 = 1 / (q49 + q50); m.m00 = (m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22) * q51; m.m01 = -(m01 * m22 * m33 - m01 * m23 * m32 - q21 * m33 + q22 * m32) * q51; m.m02 = (q25 * m33 - q26 * m32 - q27 * m33 + q28 * m32) * q51; m.m03 = -(q25 * m23 - q26 * m22 - q27 * m23 + q28 * m22 + q21 * m13 - q22 * m12) * q51; m.m10 = -(q29 * m33 - q30 * m32 - q31 * m33 + q32 * m32) * q51; m.m11 = (q35 * m33 - q36 * m32 - q37 * m33 + q38 * m32) * q51; m.m12 = -(q41 * m33 - q42 * m32 - q43 * m33 + q44 * m32) * q51; m.m13 = (q41 * m23 - q42 * m22 - q43 * m23 + q44 * m22 + q37 * m13 - q38 * m12) * q51; m.m20 = (q7 * m33 - q30 * m31 - q14 * m33 + q32 * m31) * q51; m.m21 = -(q48 * m33 - q36 * m31 - q13 * m33 + q38 * m31) * q51; m.m22 = (q45 * m33 - q42 * m31 - q6 * m33 + q44 * m31) * q51; m.m23 = -(q45 * m23 - q42 * m21 - q6 * m23 + q44 * m21 + q13 * m13 - q38 * m11) * q51; return(m); }
public void project(warp_Matrix vertexProjection, warp_Matrix normalProjection, warp_Camera camera) // Projects this vertex into camera space { pos2 = pos.transform(vertexProjection); n2 = n.transform(normalProjection); if (pos2.z < 0.001f && pos2.z > -0.0001f) { pos2.z = 0.001f; } if (camera.isOrthographic) { x = (int)pos2.x; y = (int)pos2.y; invZ = -1.0f; tx = -u; ty = -v; } else { invZ = 1.0f / pos2.z; x = (int)(pos2.x * invZ + camera.halfscreenwidth); y = (int)(pos2.y * invZ + camera.halfscreenheight); invZ = -invZ; tx = u * invZ; ty = v * invZ; } z = (int)(65536f * pos2.z); nx = ((int)(n2.x * 127 + 127)) << 16; ny = ((int)(n2.y * 127 + 127)) << 16; }
public warp_Vector transform(warp_Matrix m) // Modifies the vector by matrix m { float newx = x * m.m00 + y * m.m01 + z * m.m02 + m.m03; float newy = x * m.m10 + y * m.m11 + z * m.m12 + m.m13; float newz = x * m.m20 + y * m.m21 + z * m.m22 + m.m23; return(new warp_Vector(newx, newy, newz)); }
public warp_Matrix rotateMatrix(warp_Quaternion quat) { reset(); warp_Matrix temp = warp_Matrix.quaternionMatrix(quat); warp_Matrix result = warp_Matrix.multiply(this, temp); return(result); }
public static warp_Matrix scaleMatrix(float dx, float dy, float dz) { warp_Matrix m = new warp_Matrix(); m.m00 = dx; m.m11 = dy; m.m22 = dz; return(m); }
public static warp_Matrix shiftMatrix(float dx, float dy, float dz) // matrix for shifting { warp_Matrix m = new warp_Matrix(); m.m03 = dx; m.m13 = dy; m.m23 = dz; return(m); }
public bool RotateScene(warp_Matrix m) { if (_scene == null) { return(false); } _scene.rotate(m); return(true); }
/* * public string toString() * { * // todo * } */ public warp_Matrix getClone() { warp_Matrix m = new warp_Matrix(); m.m00 = m00; m.m01 = m01; m.m02 = m02; m.m03 = m03; m.m10 = m10; m.m11 = m11; m.m12 = m12; m.m13 = m13; m.m20 = m20; m.m21 = m21; m.m22 = m22; m.m23 = m23; m.m30 = m30; m.m31 = m31; m.m32 = m32; m.m33 = m33; return(m); }
static public warp_Quaternion matrix(warp_Matrix xfrm) { warp_Quaternion quat = new warp_Quaternion(); // Check the sum of the diagonal float tr = xfrm[0, 0] + xfrm[1, 1] + xfrm[2, 2]; if (tr > 0.0f) { // The sum is positive // 4 muls, 1 div, 6 adds, 1 trig function call float s = ( float )Math.Sqrt(tr + 1.0f); quat.W = s * 0.5f; s = 0.5f / s; quat.X = (xfrm[1, 2] - xfrm[2, 1]) * s; quat.Y = (xfrm[2, 0] - xfrm[0, 2]) * s; quat.Z = (xfrm[0, 1] - xfrm[1, 0]) * s; } else { // The sum is negative // 4 muls, 1 div, 8 adds, 1 trig function call int[] nIndex = { 1, 2, 0 }; int i, j, k; i = 0; if (xfrm[1, 1] > xfrm[i, i]) { i = 1; } if (xfrm[2, 2] > xfrm[i, i]) { i = 2; } j = nIndex[i]; k = nIndex[j]; float s = ( float )Math.Sqrt((xfrm[i, i] - (xfrm[j, j] + xfrm[k, k])) + 1.0f); quat[i] = s * 0.5f; if (s != 0.0) { s = 0.5f / s; } quat[j] = (xfrm[i, j] + xfrm[j, i]) * s; quat[k] = (xfrm[i, k] + xfrm[k, i]) * s; quat[3] = (xfrm[j, k] - xfrm[k, j]) * s; } return(quat); }
public static warp_Matrix rotateMatrix(float dx, float dy, float dz) { warp_Matrix res = new warp_Matrix(); float SIN; float COS; if (dx != 0) { warp_Matrix m = new warp_Matrix(); SIN = warp_Math.sin(dx); COS = warp_Math.cos(dx); m.m11 = COS; m.m12 = SIN; m.m21 = -SIN; m.m22 = COS; res.transform(m); } if (dy != 0) { warp_Matrix m = new warp_Matrix(); SIN = warp_Math.sin(dy); COS = warp_Math.cos(dy); m.m00 = COS; m.m02 = SIN; m.m20 = -SIN; m.m22 = COS; res.transform(m); } if (dz != 0) { warp_Matrix m = new warp_Matrix(); SIN = warp_Math.sin(dz); COS = warp_Math.cos(dz); m.m00 = COS; m.m01 = SIN; m.m10 = -SIN; m.m11 = COS; res.transform(m); } return(res); }
public void transform(warp_Matrix n) { warp_Matrix m = this.getClone(); m00 = n.m00 * m.m00 + n.m01 * m.m10 + n.m02 * m.m20; m01 = n.m00 * m.m01 + n.m01 * m.m11 + n.m02 * m.m21; m02 = n.m00 * m.m02 + n.m01 * m.m12 + n.m02 * m.m22; m03 = n.m00 * m.m03 + n.m01 * m.m13 + n.m02 * m.m23 + n.m03; m10 = n.m10 * m.m00 + n.m11 * m.m10 + n.m12 * m.m20; m11 = n.m10 * m.m01 + n.m11 * m.m11 + n.m12 * m.m21; m12 = n.m10 * m.m02 + n.m11 * m.m12 + n.m12 * m.m22; m13 = n.m10 * m.m03 + n.m11 * m.m13 + n.m12 * m.m23 + n.m13; m20 = n.m20 * m.m00 + n.m21 * m.m10 + n.m22 * m.m20; m21 = n.m20 * m.m01 + n.m21 * m.m11 + n.m22 * m.m21; m22 = n.m20 * m.m02 + n.m21 * m.m12 + n.m22 * m.m22; m23 = n.m20 * m.m03 + n.m21 * m.m13 + n.m22 * m.m23 + n.m23; }
public void preTransform(warp_Matrix n) { warp_Matrix m = this.getClone(); m00 = m.m00 * n.m00 + m.m01 * n.m10 + m.m02 * n.m20; m01 = m.m00 * n.m01 + m.m01 * n.m11 + m.m02 * n.m21; m02 = m.m00 * n.m02 + m.m01 * n.m12 + m.m02 * n.m22; m03 = m.m00 * n.m03 + m.m01 * n.m13 + m.m02 * n.m23 + m.m03; m10 = m.m10 * n.m00 + m.m11 * n.m10 + m.m12 * n.m20; m11 = m.m10 * n.m01 + m.m11 * n.m11 + m.m12 * n.m21; m12 = m.m10 * n.m02 + m.m11 * n.m12 + m.m12 * n.m22; m13 = m.m10 * n.m03 + m.m11 * n.m13 + m.m12 * n.m23 + m.m13; m20 = m.m20 * n.m00 + m.m21 * n.m10 + m.m22 * n.m20; m21 = m.m20 * n.m01 + m.m21 * n.m11 + m.m22 * n.m21; m22 = m.m20 * n.m02 + m.m21 * n.m12 + m.m22 * n.m22; m23 = m.m20 * n.m03 + m.m21 * n.m13 + m.m22 * n.m23 + m.m23; }
public bool RotateSelf(string name, warp_Matrix m) { if (_scene == null) { return(false); } warp_Object o = _scene.sceneobject(name); if (o == null) { return(false); } o.rotateSelf(m); return(true); }
public warp_Vector pointtransform(warp_Matrix m) // Modifies the point by matrix m { float newx = x * m.m00 + y * m.m01 + z * m.m02 + m.m03; float newy = x * m.m10 + y * m.m11 + z * m.m12 + m.m13; float newz = x * m.m20 + y * m.m21 + z * m.m22 + m.m23; float w = x * m.m30 + y * m.m31 + z * m.m32 + m.m33; if (w != 1.0f && w != 0f) { w = 1.0f / w; newx *= w; newy *= w; newy *= w; } return(new warp_Vector(newx, newy, newz)); }
public static warp_Matrix multiply(warp_Matrix m1, warp_Matrix m2) { warp_Matrix m = new warp_Matrix(); m.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20; m.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21; m.m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22; m.m03 = m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03; m.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20; m.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21; m.m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22; m.m13 = m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13; m.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20; m.m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21; m.m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22; m.m23 = m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23; return(m); }
public void project(warp_Matrix m) { matrix2 = m.getClone(); matrix2.transform(m); v2 = v.transform(matrix2); }
public float EstimateBoxProjectedArea(warp_Vector pos, warp_Vector size, warp_Matrix rotation) { warp_Matrix om = new warp_Matrix(); om.scale(size.x, size.y, size.z); om.transform(rotation); float xmax; float ymax; /* * if (defaultCamera.isOrthographic) * { * xmax = Math.Abs(om.m00); * ymax = Math.Abs(om.m22); * if (xmax < 1f || ymax < 1f) * return -1; * return xmax * ymax / (width * height); * } */ om.m03 = pos.x; om.m13 = pos.y; om.m23 = pos.z; warp_Vector side; warp_Vector v; float xmin; float ymin; warp_Matrix m = warp_Matrix.multiply(defaultCamera.getMatrix(), matrix); om.transform(m); float zmin; side = new warp_Vector(-1f, -1f, -1f); v = side.transform(om); xmin = v.x; xmax = xmin; ymin = v.y; ymax = ymin; zmin = v.z; side.x = 1f; v = side.transform(om); if (xmin > v.x) { xmin = v.x; } else if (xmax < v.x) { xmax = v.x; } if (ymin > v.y) { ymin = v.y; } else if (ymax < v.y) { ymax = v.y; } if (zmin > v.z) { zmin = v.z; } side.x = -1f; side.y = 1f; v = side.transform(om); if (xmin > v.x) { xmin = v.x; } else if (xmax < v.x) { xmax = v.x; } if (ymin > v.y) { ymin = v.y; } else if (ymax < v.y) { ymax = v.y; } if (zmin > v.z) { zmin = v.z; } side.x = 1f; v = side.transform(om); if (xmin > v.x) { xmin = v.x; } else if (xmax < v.x) { xmax = v.x; } if (ymin > v.y) { ymin = v.y; } else if (ymax < v.y) { ymax = v.y; } if (zmin > v.z) { zmin = v.z; } side.x = -1f; side.y = -1f; side.z = 1f; v = side.transform(om); if (xmin > v.x) { xmin = v.x; } else if (xmax < v.x) { xmax = v.x; } if (ymin > v.y) { ymin = v.y; } else if (ymax < v.y) { ymax = v.y; } if (zmin > v.z) { zmin = v.z; } side.x = 1f; v = side.transform(om); if (xmin > v.x) { xmin = v.x; } else if (xmax < v.x) { xmax = v.x; } if (ymin > v.y) { ymin = v.y; } else if (ymax < v.y) { ymax = v.y; } if (zmin > v.z) { zmin = v.z; } side.x = -1f; side.y = 1f; v = side.transform(om); if (xmin > v.x) { xmin = v.x; } else if (xmax < v.x) { xmax = v.x; } if (ymin > v.y) { ymin = v.y; } else if (ymax < v.y) { ymax = v.y; } if (zmin > v.z) { zmin = v.z; } side.x = 1f; v = side.transform(om); if (xmin > v.x) { xmin = v.x; } else if (xmax < v.x) { xmax = v.x; } if (ymin > v.y) { ymin = v.y; } else if (ymax < v.y) { ymax = v.y; } if (zmin > v.z) { zmin = v.z; } xmax -= xmin; ymax -= ymin; if (xmax < 1f || ymax < 1f) { return(-1); } return(xmax * ymax / (width * height)); }
public void transform(warp_Matrix m) { matrix.transform(m); normalmatrix.transform(m); }
public void rotateSelf(warp_Matrix m) { matrix.rotateSelf(m); normalmatrix.rotateSelf(m); }
public void project(warp_Matrix normalProjection) { n2 = n.transform(normalProjection); distZ = getDistZ(); }
public static warp_Object TUBE(warp_Vector[] path, float r, int steps, bool closed) { warp_Vector[] circle = new warp_Vector[steps]; float angle; for (int i = 0; i < steps; i++) { angle = 2 * 3.14159265f * (float)i / (float)steps; circle[i] = new warp_Vector(r * warp_Math.cos(angle), r * warp_Math.sin(angle), 0f); } warp_Object newObject = new warp_Object(); int segments = path.GetLength(0); warp_Vector forward, up, right; warp_Matrix frenetmatrix; warp_Vertex tempvertex; float relx, rely; int a, b, c, d; for (int i = 0; i < segments; i++) { // Calculate frenet frame matrix if (i != segments - 1) { forward = warp_Vector.sub(path[i + 1], path[i]); } else { if (!closed) { forward = warp_Vector.sub(path[i], path[i - 1]); } else { forward = warp_Vector.sub(path[1], path[0]); } } forward.normalize(); up = new warp_Vector(0f, 0f, 1f); right = warp_Vector.getNormal(forward, up); up = warp_Vector.getNormal(forward, right); frenetmatrix = new warp_Matrix(right, up, forward); frenetmatrix.shift(path[i].x, path[i].y, path[i].z); // Add nodes relx = (float)i / (float)(segments - 1); for (int k = 0; k < steps; k++) { rely = (float)k / (float)steps; tempvertex = new warp_Vertex(circle[k].transform(frenetmatrix)); tempvertex.u = relx; tempvertex.v = rely; newObject.addVertex(tempvertex); } } for (int i = 0; i < segments - 1; i++) { for (int k = 0; k < steps - 1; k++) { a = i * steps + k; b = a + 1; c = a + steps; d = b + steps; newObject.addTriangle(a, c, b); newObject.addTriangle(b, c, d); } a = (i + 1) * steps - 1; b = a + 1 - steps; c = a + steps; d = b + steps; newObject.addTriangle(a, c, b); newObject.addTriangle(b, c, d); } return(newObject); }
public void rotateSelf(warp_Matrix m) { preTransform(m); }
public void rotate(warp_Matrix m) { transform(m); }
public void render(warp_Camera cam) { rasterizer.rebuildReferences(this); warp_Math.clearBuffer(zBuffer, zFar); //System.Array.Copy(screen.zBuffer,0,zBuffer,0,zBuffer.Length); if (scene.environment.background != null) { screen.drawBackground(scene.environment.background, 0, 0, screen.width, screen.height); } else { screen.clear(scene.environment.bgcolor); } cam.setScreensize(screen.width, screen.height); scene.prepareForRendering(); emptyQueues(); // Project warp_Matrix m = warp_Matrix.multiply(cam.getMatrix(), scene.matrix); warp_Matrix nm = warp_Matrix.multiply(cam.getNormalMatrix(), scene.normalmatrix); warp_Matrix vertexProjection, normalProjection; warp_Object obj; warp_Triangle t; warp_Vertex v; warp_Material objmaterial; const double log2inv = 1.4426950408889634073599246810019; int w = screen.width; int h = screen.height; int minx; int miny; int maxx; int maxy; for (int id = 0; id < scene.objects; ++id) { obj = scene.wobject[id]; objmaterial = obj.material; if (objmaterial == null) { continue; } if (!obj.visible) { continue; } if (objmaterial.opaque && objmaterial.reflectivity == 0) { continue; } vertexProjection = obj.matrix.getClone(); normalProjection = obj.normalmatrix.getClone(); vertexProjection.transform(m); normalProjection.transform(nm); minx = int.MaxValue; miny = int.MaxValue; maxx = int.MinValue; maxy = int.MinValue; for (int i = 0; i < obj.vertices; ++i) { v = obj.fastvertex[i]; v.project(vertexProjection, normalProjection, cam); v.clipFrustrum(w, h); if (minx > v.x) { minx = v.x; } if (maxx < v.x) { maxx = v.x; } if (miny > v.y) { miny = v.y; } if (maxy < v.y) { maxy = v.y; } } maxx -= minx; maxy -= miny; if (maxy > maxx) { maxx = maxy + 1; } else { maxx++; } obj.projectedmaxMips = (int)Math.Ceiling((Math.Log(maxx) * log2inv)); obj.cacheMaterialData(); if (objmaterial.opaque) { rasterizer.loadFastMaterial(obj); for (int i = 0; i < obj.triangles; ++i) { t = obj.fasttriangle[i]; t.project(normalProjection); if (t.clipFrustrum(w, h)) { rasterizer.render(t); } } } else { for (int i = 0; i < obj.triangles; ++i) { t = obj.fasttriangle[i]; t.project(normalProjection); if (t.clipFrustrum(w, h)) { transparentQueue.Add(t); } } } } //screen.lockImage(); warp_Triangle[] tri; obj = null; tri = getTransparentQueue(); if (tri != null) { transparentQueue.Clear(); for (int i = 0; i < tri.GetLength(0); i++) { if (obj != tri[i].parent) { obj = tri[i].parent; rasterizer.loadFastMaterial(obj); } rasterizer.render(tri[i]); } } //screen.unlockImage(); }
public void normalize() { objectsNeedRebuild = true; rebuild(); warp_Vector min, max, tempmax, tempmin; if (objects == 0) { return; } matrix = new warp_Matrix(); normalmatrix = new warp_Matrix(); max = wobject[0].maximum(); min = wobject[0].maximum(); for (int i = 0; i < objects; i++) { tempmax = wobject[i].maximum(); tempmin = wobject[i].maximum(); if (tempmax.x > max.x) { max.x = tempmax.x; } if (tempmax.y > max.y) { max.y = tempmax.y; } if (tempmax.z > max.z) { max.z = tempmax.z; } if (tempmin.x < min.x) { min.x = tempmin.x; } if (tempmin.y < min.y) { min.y = tempmin.y; } if (tempmin.z < min.z) { min.z = tempmin.z; } } float xdist = max.x - min.x; float ydist = max.y - min.y; float zdist = max.z - min.z; float xmed = (max.x + min.x) / 2; float ymed = (max.y + min.y) / 2; float zmed = (max.z + min.z) / 2; float diameter = (xdist > ydist) ? xdist : ydist; diameter = (zdist > diameter) ? zdist : diameter; normalizedOffset = new warp_Vector(xmed, ymed, zmed); normalizedScale = 2 / diameter; shift(normalizedOffset.reverse()); scale(normalizedScale); }