void PS3_setScanLineType(float type) { scanline.setW(type); //scanline type -> horizontal lines }
Matrix4 Matrix4::GetRotate(const Vector4& from, const Vector4& to) { Vector4 axis = from.Cross(to); axis.Normalize(); float degrees = from.GetAngleBetween(to); return GetRotate(degrees, axis); }
Vector4* findNormalToTriangle(double xS, double yS, double zS, Triangle& triangle){ double x0 = triangle.v[0].position[0]; double y0 = triangle.v[0].position[1]; double z0 = triangle.v[0].position[2]; double x1 = triangle.v[1].position[0]; double y1 = triangle.v[1].position[1]; double z1 = triangle.v[1].position[2]; double x2 = triangle.v[2].position[0]; double y2 = triangle.v[2].position[1]; double z2 = triangle.v[2].position[2]; //Calculate the vertices of the triangle. auto_ptr<Vector4> P0(new Vector4()); P0->SetVector4(x0,y0,z0,1.0f); auto_ptr<Vector4> P1(new Vector4()); P1->SetVector4((float)x1,(float)y1,(float)z1,1.0f); auto_ptr<Vector4> P2(new Vector4()); P2->SetVector4((float)x2,(float)y2,(float)z2,1.0f); auto_ptr<Vector4> P(new Vector4()); P->SetVector4((float)xS,(float)yS,(float)zS,1.0f); //Vector from one vertex to other vertex. auto_ptr<Vector4> Edge01(P0->Subtract(*P1, *P0)); auto_ptr<Vector4> Edge12(P1->Subtract(*P2, *P1)); auto_ptr<Vector4> Edge20(P2->Subtract(*P0, *P2)); //Area of the complete triangle. double area_P0P1P2 = (0.5*Edge01->CrossProduct(*Edge01, *Edge20)->GetMagnitude()); assert(area_P0P1P2 > 0); //Area of PP0P2 auto_ptr<Vector4> EdgePP2(new Vector4()); EdgePP2->SetVector4(xS-x2, yS-y2, zS-z2,1); double area_PP0P2 = (0.5*Edge20->CrossProduct(*Edge20, *EdgePP2)->GetMagnitude()); assert(area_PP0P2 >= 0.0); //Area of PP1P2 double area_PP1P2 = (0.5 * EdgePP2->CrossProduct(*EdgePP2, *Edge12)->GetMagnitude()); assert(area_PP1P2 >= 0); //Area of PP0P1 auto_ptr<Vector4> EdgePP0(new Vector4()); EdgePP0->SetVector4(xS-x0, yS-y0, zS-z0,1); double area_PP0P1 = (0.5*Edge01->CrossProduct(*Edge01, *EdgePP0)->GetMagnitude()); assert(area_PP0P1 >= 0);//I am here double alpha = area_PP1P2/area_P0P1P2; double beta = area_PP0P2/area_P0P1P2; double gamma = area_PP0P1/area_P0P1P2; double n0_x = triangle.v[0].normal[0]; double n0_y = triangle.v[0].normal[1]; double n0_z = triangle.v[0].normal[2]; auto_ptr<Vector4> N0(new Vector4()); N0->SetVector4(n0_x, n0_y, n0_z, 1); double n1_x = triangle.v[1].normal[0]; double n1_y = triangle.v[1].normal[1]; double n1_z = triangle.v[1].normal[2]; auto_ptr<Vector4> N1(new Vector4()); N1->SetVector4(n1_x, n1_y, n1_z, 1); double n2_x = triangle.v[2].normal[0]; double n2_y = triangle.v[2].normal[1]; double n2_z = triangle.v[2].normal[2]; auto_ptr<Vector4> N2(new Vector4()); N2->SetVector4(n2_x, n2_y, n2_z, 1); N0->Elongate(alpha); N1->Elongate(beta); N2->Elongate(gamma); Vector4* normalTemp = N0->Add(*N0, *N1); Vector4* normal = N0->Add(*normalTemp, *N2); delete normalTemp; normal->ConvertToUnit(); return normal; }
Vector4 Vector4::Normalize(const Vector4& argVec) { return argVec / argVec.Magnitude(); };
void GraphicalPlane::Render(const Camera* camera) { // 描画しないならここで関数終了 if(!_renders) return; // 分割読み込みした場合の画像範囲選択 if(_previousNumber != _number) { Vertex* vertex; _mesh->GetMesh()->LockVertexBuffer( 0, (void**)&vertex ); vertex[0]._uv.x = (float)_rects[_number].left / _textures[0]->GetImageInfo().Width; vertex[0]._uv.y = (float)_rects[_number].bottom / _textures[0]->GetImageInfo().Height; vertex[1]._uv.x = (float)_rects[_number].right / _textures[0]->GetImageInfo().Width; vertex[1]._uv.y = (float)_rects[_number].bottom / _textures[0]->GetImageInfo().Height; vertex[2]._uv.x = (float)_rects[_number].left / _textures[0]->GetImageInfo().Width; vertex[2]._uv.y = (float)_rects[_number].top / _textures[0]->GetImageInfo().Height; vertex[3]._uv.x = (float)_rects[_number].right / _textures[0]->GetImageInfo().Width; vertex[3]._uv.y = (float)_rects[_number].top / _textures[0]->GetImageInfo().Height; _mesh->GetMesh()->UnlockIndexBuffer(); _previousNumber = _number; } // ワールド行列設定 Matrix SclMtx, RotMtx, PosMtx, WldMtx, WVPMtx; // 拡縮 D3DXMatrixScaling(&SclMtx, _scale.x, _scale.y, _scale.z); // 回転 // クォータニオンか回転行列かXYZ指定か this->Evaluate(); RotMtx = _worldRotationMatrix; // ビルボードの場合 if(_isBillBoard) { Vector3 cameraPosition = camera->GetEye() ; GetBillBoardRotation(&_position, &cameraPosition, &RotMtx); } // 位置 D3DXMatrixTranslation(&PosMtx, _position.x, _position.y, _position.z); // カリングを設定 GraphicsManager::_device->SetRenderState(D3DRS_CULLMODE, _cullingState); // デバッグ用 //GraphicsManager::_device->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME ); // シェーダを使用する場合カメラのビュー行列(0)、プロジェクション行列(1)をワールド行列に合成 WldMtx = SclMtx * RotMtx * PosMtx; WVPMtx = WldMtx * camera->GetMatrix(ViewBehavior::VIEW) * camera->GetMatrix(ViewBehavior::PROJECTION); // カメラの座標をシェーダに使用するための行列変換 Matrix CamMtx = WldMtx * camera->GetMatrix(ViewBehavior::VIEW); D3DXMatrixInverse(&CamMtx, NULL, &CamMtx); Vector4 EyePos = Vector4( camera->GetEye().x, camera->GetEye().y, camera->GetEye().z, 1 ); EyePos.Transform(CamMtx); D3DXVec4Normalize((D3DXVECTOR4*)&EyePos, (D3DXVECTOR4*)&EyePos); // シェーダ設定 _shader->SetTechnique(); // シェーダにワールド * ビュー * プロジェクション行列を渡す _shader->SetWVPMatrix(WVPMtx); // シェーダー特有の値の設定 _shader->ApplyEffect(RotMtx, EyePos); HRESULT hr; // 3D モデルのパーツ分ループして描画 for(size_t i = 0 ; i < _mesh->GetMaterialNumber(); i++) { // テクスチャが存在しない場合のカラー D3DXVECTOR4 vec4 = D3DXVECTOR4(1.0,1.0,1.0,1.0); // 格パーツに対応するテクスチャを設定 // シェーダにテクスチャを渡す if(NULL != _textures[i]) { LPDIRECT3DTEXTURE9 texture = _textures[i]->GetTextureData(); // シェーダにカラーを渡す _shader->SetColor(_colorRGBA); _shader->SetTexture(texture); }else _shader->SetColor(vec4); // シェーダの使用開始 _shader->BeginShader(); // シェーダのパス設定 _shader->BeginPass(_addsBlend); // パーツの描画 if(SUCCEEDED(GraphicsManager::_device->BeginScene())) { _mesh->GetMesh()->DrawSubset(i); V(GraphicsManager::_device->EndScene()); } // パス終了 _shader->EndPass(); // シェーダ終了 _shader->EndShader(); } }
void Rasterizer::rasterizeTriangle(Vector4 a, Vector4 b, Vector4 c, float c1, float c2, float c3) { float alpha, beta, gamma, denom; float x1 = a[0]; float y1 = a[1]; float x2 = b[0]; float y2 = b[1]; float x3 = c[0]; float y3 = c[1]; float top = max(max(y1, y2), y3); if (top >= window_height) top = window_height - 1; float bottom = min(min(y1, y2), y3); if (bottom < 0) bottom = 0; float left = min(min(x1, x2), x3); if (left < 0) left = 0; float right = max(max(x1, x2), x3); if (right >= window_width) right = window_width - 1; for (int row = bottom; row <= top; row++) { for (int col = left; col <= right; col++) { Vector3 v0 = Vector3(x3 - x1, y3 - y1, 0); Vector3 v1 = Vector3(x2 - x1, y2 - y1, 0); Vector3 v2 = Vector3(col - x1, row - y1, 0); denom = v0.dot(v0) * v1.dot(v1) - v0.dot(v1) * v1.dot(v0); alpha = (v1.dot(v1) * v2.dot(v0) - v1.dot(v0) * v2.dot(v1)) / denom; beta = (v0.dot(v0) * v2.dot(v1) - v0.dot(v1) * v2.dot(v0)) / denom; gamma = 1 - alpha - beta; Vector3 P = a.toVector3() + (c - a).toVector3().scale(alpha) + (b - a).toVector3().scale(beta); float z = P[2]; if (Globals::interp) { c1 = row / c1; c2 = col / c2; c3 = z / c3; } if (alpha > 0 && alpha < 1 && beta > 0 && beta < 1 && gamma > 0 && gamma < 1) { if (Globals::zbuf) { update_zbuffer(col, row, c1, c2, c3, z); } else drawPoint(col, row, c1, c2, c3); } } } }
// pocitanie funkcie pre vsetky trojuholniky, O(n2) void CSDFController::Compute(LinkedList<Face>* triangles, Octree* root) { float min = FLOAT_MAX; float max = 0.0; unsigned int n_rays = 30; float angle = 120.0f; unsigned int counter = 0; //------------------prealocated variables------------------ Vector4 tangens, normal, binormal; Mat4 t_mat; std::vector<float> rays; std::vector<float> weights; // precompute those N rays srand (123); // initial seed for random number generator float* rndy = new float[n_rays]; float* rndx = new float[n_rays]; for(unsigned int i = 0; i < n_rays; i++) { rndy[i] = float(rand()%int(angle / 2)); rndx[i] = float(rand()%(360)); if(rndy[i] == 0.0) rndy[i] = 0.5; } float dist = FLOAT_MAX; float dist2 = FLOAT_MAX; float theta = 0.0f; bool intersected = false; LinkedList<Face>* face_list = NULL; LinkedList<Face>::Cell<Face>* intersected_face = NULL; //------------------prealocated variables------------------ LinkedList<Face>::Cell<Face>* current_face = triangles->start; while(current_face != NULL) { // vypocet TNB vektorov a matice ComputeTNB(current_face->data, tangens, normal, binormal); t_mat = Mat4(tangens, normal, binormal); rays.clear(); weights.clear(); for(unsigned int i = 0; i < n_rays; i++) { Vector4 ray = CalcRayFromAngle(rndx[i], rndy[i]) * t_mat; ray.Normalize(); dist = FLOAT_MAX; face_list = GetFaceList(triangles, root, current_face->data->center, ray); intersected_face = face_list->start; while(intersected_face != NULL) { if(current_face == intersected_face) { intersected_face = intersected_face->next; continue; } dist2 = FLOAT_MAX; intersected = rayIntersectsTriangle(current_face->data->center, ray, intersected_face->data->v[0]->P, intersected_face->data->v[1]->P, intersected_face->data->v[2]->P, dist2); if(intersected == true) { theta = acos( (ray * intersected_face->data->normal) / (ray.Length() * intersected_face->data->normal.Length()) ); theta = theta * float(180.0 / M_PI); //loggger->logInfo(MarshalString("pridany ray s thetou: " + theta)); if((theta < 90.0f) && (dist2 < dist)) dist = dist2; } intersected_face = intersected_face->next; } if(dist < (FLOAT_MAX - 1.0f)) { //loggger->logInfo(MarshalString("pridany ray s dlzkou: " + dist)); rays.push_back(dist); weights.push_back(180.0f - rndy[i]); } //if(root != NULL) //delete face_list; // generated list, bez prealokovania } if(rays.size() > 0) { current_face->data->ComputeSDFValue(rays, weights); if(current_face->data->diameter->value < min) min = current_face->data->diameter->value; if(current_face->data->diameter->value > max) max = current_face->data->diameter->value; } counter = counter + 1; current_face = current_face->next; } fc_list->Clear(); oc_list->Clear(); delete [] rndy; delete [] rndx; // postprocessing - smoothing and normalization //float kernel[] = {1.0,4.0,6.0,4.0,1.0}; float* kernel = ComputeGaussianKernel(kernel_size); current_face = triangles->start; while(current_face != NULL) { Smooth(current_face->data, kernel, kernel_size); current_face->data->diameter->Normalize1(min, max, 4.0); current_face->data->diameter->Normalize2(0, max, 4.0); //tmp->data->diameter->Normalize2(0, diagonal, 4.0); current_face = current_face->next; } delete kernel; }
bool Mesh::CullPolygons(const ViewFrustum& frustum, const Maths::Vector4& camPos) { int cullCount = 0; for ( int i = 0; i < m_numPolys; ++i ) { if ( m_polys[i].IsCulled ) { cullCount++; continue; } int count = 0; for ( int vv = 0; vv < 3; ++vv ) { //Vector4 point = m_transformed[ m_polys[i].Indices[vv] ].Position - camPos; Vector4 point = m_transformed[ m_polys[i].Indices[vv] ].Position - m_verts[ m_polys[i].Indices[vv] ]; float result = point.DotProduct( frustum.Left.Normal ); if ( result > 0.0f ) { count++; m_transformed[ m_polys[i].Indices[vv] ].IsCulled = true; continue; } result = point.DotProduct( frustum.Right.Normal ); if ( result > 0.0f ) { count++; m_transformed[ m_polys[i].Indices[vv] ].IsCulled = true; continue; } result = point.DotProduct( frustum.Top.Normal ); if ( result > 0.0f ) { count++; m_transformed[ m_polys[i].Indices[vv] ].IsCulled = true; continue; } result = point.DotProduct( frustum.Bottom.Normal ); if ( result > 0.0f ) { count++; m_transformed[ m_polys[i].Indices[vv] ].IsCulled = true; continue; } //result = point.DotProduct( frustum.Near.Normal ); //if ( result > 0.0f ) //{ // count++; // m_transformed[ m_polys[i].Indices[vv] ].IsCulled = true; // continue; //} //result = point.DotProduct( frustum.Far.Normal ); //if ( result > 0.0f ) //{ // count++; // m_transformed[ m_polys[i].Indices[vv] ].IsCulled = true; // continue; //} } if ( count == 3 ) { cullCount++; m_polys[i].IsCulled = true; } } return ( cullCount == m_numPolys ); }
void Shader::uniform(const string &nom,const Vector4 &p,int offset) { int loc=uniform(nom); glUniform4fv(loc+offset,1,p.fv()); }
void Mesh::CalculateLightingDirectional(const LightDirectional& light, int numLights, const Vector4& camera) { Maths::Vector4 total; Maths::Vector4 temp; Maths::Vector4 l( light.Position.X, light.Position.Y, light.Position.Z, 1.0f ); Maths::Vector4 n( 0, 0, 0, 0 ); BYTE r, g, b; float diff, spec = 0; m_noLight = false; l.Normalize(); for ( int i = 0; i < m_numVerts; ++i ) { if ( !m_transformed[i].IsCulled ) { //reset the colout to black total.X = 0; //Red total.Y = 0; //green total.Z = 0; //blue for ( int j = 0; j < numLights; ++j ) { Maths::Vector4 d; //modulate intensity with coresponding reflectance co-efficient values temp.X = light.Colour.GetR() * light.Intensity.X; temp.Y = light.Colour.GetG() * light.Intensity.Y; temp.Z = light.Colour.GetB() * light.Intensity.Z; n = m_transformed[i].Normal; n.Normalize(); //attentuate the rgb values with lambertian attenuation diff = max(0.0, l.DotProduct( n )); Vector4 toEye = m_transformed[i].Position - camera; Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) ); toEye.Normalize(); reflect.Normalize(); float specPower = 1.0f; spec = pow( max( reflect.DotProduct( toEye ), 0.0f ), specPower ) * 0.01f; if ( diff <= 0.0f ) spec = 0.0f; temp.X = temp.X * ( (diff + spec) * m_kd_red ); temp.Y = temp.Y * ( (diff + spec) * m_kd_green ); temp.Z = temp.Z * ( (diff + spec) * m_kd_blue ); //temp.X = temp.X * ( diff * m_kd_red + spec ) ); //temp.Y = temp.Y * ( diff * m_kd_green + spec ) ); //temp.Z = temp.Z * ( diff * m_kd_blue + spec ) ); total = total + temp; } if ( total.X > 255.0f ) total.X = 255.0f; if ( total.Y > 255.0f ) total.Y = 255.0f; if ( total.Z > 255.0f ) total.Z = 255.0f; if ( total.X < 0.0f ) total.X = 0.0f; if ( total.Y < 0.0f ) total.Y = 0.0f; if ( total.Z < 0.0f ) total.Z = 0.0f; r = (BYTE)total.X; g = (BYTE)total.Y; b = (BYTE)total.Z; m_transformed[i].Colour = Gdiplus::Color::MakeARGB( 255, r, g, b ); } } }
void Mesh::CalculateLightingPoint( const std::vector<LightPoint>& light, int numLight, const Maths::Vector4& camera) { Maths::Vector4 l; Maths::Vector4 temp, result, n, p; Maths::Vector4 cof( 1.0f, 1.0f, 10.0f ); BYTE r, g, b; float distance = 0; float att = 0; float a = 0.05f; float bb = 0.05f; float c = 0.05f; float dif, spec; m_noLight = false; for ( int i = 0; i < m_numVerts; ++i ) { if ( !m_transformed[i].IsCulled ) { result.X = 0; //Red result.Y = 0; //green result.Z = 0; //blue for ( int j = 0; j < numLight; ++j ) { p = light[j].Position; l = p - m_transformed[i].Position; distance = l.Length(); //calculate the attenuation value att = 1 / (a + ( distance * bb ) + ( distance * distance ) * c ); if ( att < 0 ) att = 0; temp.X = light[j].Colour.GetR(); temp.Y = light[j].Colour.GetG(); temp.Z = light[j].Colour.GetB(); n = m_transformed[i].Normal; n.Normalize(); dif = max( 0.0, l.DotProduct( n ) ) * att; // calculate the speculation //Vector4 toEye = m_transformed[i].Position - camera; //Vector4 half = camera + p / 2; //toEye.Normalize(); //half.Normalize(); //float specPower = 1.0f; //float spec = pow( max( n.DotProduct( half ), 0.0f ), specPower ) * att; Vector4 toEye = m_transformed[i].Position - camera; Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) ); toEye.Normalize(); reflect.Normalize(); float specPower = 1.0f; float spec = pow( max( reflect.DotProduct( toEye ), 0.0f ), specPower ) * att; temp.X = temp.X * ( (dif + spec) * m_kd_red ); temp.Y = temp.Y * ( (dif + spec) * m_kd_green ); temp.Z = temp.Z * ( (dif + spec) * m_kd_blue ); //temp.X = temp.X * ( dif * m_kd_red ) ); //temp.Y = temp.Y * ( dif * m_kd_green ) ); //temp.Z = temp.Z * ( dif * m_kd_blue ) ); result += temp; } //set colour if ( result.X > 255.0f ) result.X = 255.0f; if ( result.Y > 255.0f ) result.Y = 255.0f; if ( result.Z > 255.0f ) result.Z = 255.0f; if ( result.X < 0.0f ) result.X = 0.0f; if ( result.Y < 0.0f ) result.Y = 0.0f; if ( result.Z < 0.0f ) result.Z = 0.0f; r = (BYTE)result.X; g = (BYTE)result.Y; b = (BYTE)result.Z; m_transformed[i].Colour = Gdiplus::Color::MakeARGB( 255, r, g, b ); } } }
void Mesh::CalculateFlatLightingPoint(const std::vector<LightPoint>& light, int numLights, const Vector4& camera) { Maths::Vector4 l; Maths::Vector4 temp, result, n, p; BYTE r, g, b; float distance = 0; float att = 0; float a = 0.05f; float bb = 0.05f; float c = 0.05f; float dif, spec; m_noLight = false; for ( int i = 0; i < m_numPolys; ++i ) { result.X = 0; //Red result.Y = 0; //green result.Z = 0; //blue if ( !m_polys[i].IsCulled ) { for ( int j = 0; j < numLights; ++j ) { //get the position of the light and calculate the //distance between the object and the lifght p = light[j].Position; l = p - m_transformed[ m_polys[i].Indices[0] ].Position; distance = l.Length(); //calculate the attenuation value att = 1 / (a + ( distance * bb ) + ( distance * distance ) * c ); if ( att < 0) att = 0; temp.X = light[j].Colour.GetR(); temp.Y = light[j].Colour.GetG(); temp.Z = light[j].Colour.GetB(); // get the normalized value of the polygon normals //n = m_polys[i]._normalN; //n.Normalize(); // calculate the diffuse value dif = max( l.DotProduct( m_polys[i].NormalN ), 0.0f ) * att; // multiply dif with materials // calculate the speculation //Vector4 toEye = m_transformed[ m_polys[i]._indices[0] ]._position - camera; //Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) ); //toEye.Normalize(); //reflect.Normalize(); //float specPower = 1.0f; //float spec = pow( max( reflect.DotProduct( toEye ), 0.0f ), specPower ) * att; Vector4 toEye = m_transformed[ m_polys[i].Indices[0] ].Position - camera; Vector4 half = camera + p / 2; toEye.Normalize(); half.Normalize(); float specPower = 1.0f; float spec = pow( max( n.DotProduct( half ), 0.0f ), specPower ) * att; temp.X = temp.X * ( (dif + spec) * m_kd_red ); temp.Y = temp.Y * ( (dif + spec) * m_kd_green ); temp.Z = temp.Z * ( (dif + spec) * m_kd_blue ); result += temp; } //set colour if ( result.X > 255.0f ) result.X = 255; if ( result.Y > 255.0f ) result.Y = 255; if ( result.Z > 255.0f ) result.Z = 255; if ( result.X < 0.0f ) result.X = 0; if ( result.Y < 0.0f ) result.Y = 0; if ( result.Z < 0.0f ) result.Z = 0; r = (BYTE)result.X; g = (BYTE)result.Y; b = (BYTE)result.Z; m_polys[i].Colour = Gdiplus::Color::MakeARGB( 255, r, g, b ); } } }
void Mesh::CalculateFlatLightingDirectional(const LightDirectional &light, int numLights, const Vector4& cameraPos, const Matrix4& view) { Maths::Vector4 total, temp; Maths::Vector4 reflect; Maths::Vector4 v = cameraPos; Maths::Vector4 l( light.Position.X, light.Position.Y, light.Position.Z, 1.0f ); Maths::Vector4 n( 0, 0, 0 ); Maths::Vector4 t, halfWay; BYTE r, g, b; float spec = 0; float diff = 0; float ave = 0; m_noLight = false; //workout the "halfway" vector for specularity ave = v.Length(); //halfWay = ( v + l ) / ave; //halfWay.Normalize(); //normalize the light position l.Normalize(); for ( int i = 0; i < m_numPolys; ++i ) { if ( !m_polys[i].IsCulled ) { //reset the colout to black total.X = 0; //Red total.Y = 0; //green total.Z = 0; //blue for ( int j = 0; j < numLights; ++j ) { //store intensity to corresponding variables //modulate intensity with coresponding reflectance co-efficient values temp.X = light.Colour.GetR() * light.Intensity.X; temp.Y = light.Colour.GetG() * light.Intensity.Y; temp.Z = light.Colour.GetB() * light.Intensity.Z; //reflect = ( 2 * ( m_polys[i]._normal.DotProduct( light._position ) ) * ( m_polys[i]._normal - light ); n.SetValues( m_polys[i].Normal.X, m_polys[i].Normal.Y, m_polys[i].Normal.Z, 1.0f ); n.Normalize(); //attentuate the rgb values with lambertian attenuation diff = max( 0.0f, l.DotProduct( n ) ); //calculate specular coponent Vector4 toEye; Matrix4::Transform( view, m_transformed[ m_polys[i].Indices[0] ].Position, toEye ); toEye.Normalize(); float r = max( 0, m_transformed[ m_polys[i].Indices[0] ].Normal.DotProduct( l ) ); Vector4 reflect = m_transformed[ m_polys[i].Indices[0] ].Normal; reflect.Multiply( 2 * r ); reflect.Subtract( l ); //Vector4 toEye = m_transformed[ m_polys[i]._indices[0] ]._position - viewer; //Vector4 reflect = ( n - l ) * ( 2 * ( n.DotProduct( l ) ) ); toEye.Normalize(); reflect.Normalize(); float specPower = 1.0f; float spec = 0; //max( 0, pow( max( 0.0f, reflect.DotProduct( toEye ) ), specPower ) ) * m_specular; if ( diff <= 0.0f ) spec = 0.0f; temp.X = temp.X * ( (diff + spec) * m_kd_red ); temp.Y = temp.Y * ( (diff + spec) * m_kd_green ); temp.Z = temp.Z * ( (diff + spec) * m_kd_blue ); total = total + temp; } //clamp the values if (total.X > 255) total.X = 255; if (total.Y > 255) total.Y = 255; if (total.Z > 255) total.Z = 255; if (total.X < 0) total.X = 0; if (total.Y < 0) total.Y = 0; if (total.Z < 0) total.Z = 0; r = (BYTE)total.X; g = (BYTE)total.Y; b = (BYTE)total.Z; m_polys[i].Colour = Gdiplus::Color::MakeARGB(255, r, g, b); } } }
int PS3_initialize(void) { s32 ret,i; void *host_addr = memalign(1024*1024, HOST_SIZE); s32 pressedCounter = 0; Matrix4 rotX,rotY; sysModuleLoad(SYSMODULE_FS); ioPadInit(7); write_log("PS3_initialize...\n"); int videoMode = getVideoMode(); init_screen(host_addr, HOST_SIZE, videoMode); init_shader(); //init_texture(); //init_texture_ui(); quad = createQuad(10.0f, 0.0f); quad_ui = createQuad(10.0f, 0.5f); rotX = Matrix4::rotationX(DEGTORAD(0.0f)); rotY = Matrix4::rotationY(DEGTORAD(180.0f)); modelMatrixBase = rotX * rotY; modelMatrixUi = rotX * rotY; modelMatrix = rotX * rotY; ret = atexit(program_exit_callback); ret = sysUtilRegisterCallback(0,sysutil_exit_callback,NULL); P = transpose(Matrix4::orthographic(-5.0f, 5.0f, -5.0f, 5.0f, -10.0f, 10.0f)); // by default sretch video to 90% of the screen in X axis (compensate output to wide screens) scaler.setX(1.0f); scaler.setY(1.0f); scaler.setZ(1.0f); translator.setX(0.0f); translator.setY(0.0f); translator.setZ(0.0f); setRenderTarget(curr_fb); scanline.setX(200.0f); //desnity scanline.setY(2.0f); //contrast scanline.setZ(0.7f); //brightnes scanline.setW(0.1f); //scanline type -> horizontal lines scanlineUi.setX(0); //no desnsity modifier scanlineUi.setY(0); //no contrast modifier scanlineUi.setZ(1.0f); //full brightnes scanlineUi.setW(0.0f); //scanline type -> no scanlines running = 1; masterVolume = 32768.0f * 2.8f; // 80% volumeMuted = 0; return 0; }
/* Normalize */ Vector4 Normalize(Vector4 toNorm) { toNorm.Normalize(); return toNorm; }
void Shader::uniform(int loc,const Vector4 &p,int offset) { glUniform4fv(loc+offset,1,p.fv()); }
/* AngleBetween */ float Vector4::AngleBetween(Vector4& vec) { return acos(DotProduct(vec)/(Magnitude() * vec.Magnitude())); }
bool Asteroid::update() { toWorld = translation * toWorld; float x = toWorld.m[3][0]; float y = toWorld.m[3][1]; float z = toWorld.m[3][2]; if (x < -251 || x > 251 || y < -251 || y > 251 || z < -251 || z > 251) { return false; } SolarSystem * solar = &Globals::solarSystem; for (list<SolarPlanet*>::iterator it = solar->planets.begin(); it != solar->planets.end(); it++) { Matrix4 newToWorld; Vector3 newPoint; Vector3 newDiff; SolarPlanet* planet = (*it); Vector3 pos = planet->position; Vector3 asteroid_pos = toWorld.getTranslate().toVector3(); Vector3 diff = asteroid_pos - pos; float mag = diff.magnitude(); if(!collided){ if (mag < planet->radius) { planet->changeColor(); collided = true; unsigned long range = 268435455; float genSeed = ((float)rand() / (float)RAND_MAX) * range; gShape = new GShape((unsigned long)genSeed); Vector4 dir = toWorld.getTranslate() - pos.toVector4(0); Vector3 newDir = dir.toVector3(); Vector3 face = Vector3(0, 0, 1); float angle = face.angle(newDir); Vector3 axis = face.cross(newDir).normalize(); Matrix4 rot; rot = rot.makeRotateArbitrary(axis, angle); toWorld.m[3][0] = pos[0]; toWorld.m[3][1] = pos[1]; toWorld.m[3][2] = pos[2]; toWorld = toWorld * rot; toWorld.m[3][0] = asteroid_pos[0]; toWorld.m[3][1] = asteroid_pos[1]; toWorld.m[3][2] = asteroid_pos[2]; translation.identity(); float xT = dir[0] / (planet->radius * 2); float yT = dir[1] / (planet->radius * 2); float zT = dir[2] / (planet->radius * 2); /*xT = xT / 200; yT = yT / 200; zT = zT / 200;*/ translation = translation.makeTranslate(xT, yT, zT); justReverted = true; break; } //return false; } else { Vector3 basePos = gShape->baseToWorld.getTranslate().toVector3(); Vector3 leftPos = gShape->leftToWorld.getTranslate().toVector3(); Vector3 rightPos = gShape->rightToWorld.getTranslate().toVector3(); float baseRadius = gShape->A_size * 1.7; float leftRadius = gShape->B_size * 1.7; float rightRadius = gShape->C_size * 1.7; diff = basePos - pos; if (diff.magnitude() <= baseRadius + planet->radius) { newToWorld = toWorld * translation; newPoint = newToWorld.getTranslate().toVector3(); newDiff = newPoint - pos; if (newDiff.magnitude() > diff.magnitude()) { break; } else { if (!justReverted) { genColorz(gShape->baseBoundSphereColor); translation.m[3][0] = -translation.m[3][0]; translation.m[3][1] = -translation.m[3][1]; translation.m[3][2] = -translation.m[3][2]; justReverted = true; } break; } } diff = leftPos - pos; if (diff.magnitude() <= leftRadius + planet->radius) { newToWorld = toWorld * translation; newPoint = newToWorld.getTranslate().toVector3(); newDiff = newPoint - pos; if (newDiff.magnitude() > diff.magnitude()) { break; } else { if (!justReverted) { genColorz(gShape->leftBoundSphereColor); translation.m[3][0] = -translation.m[3][0]; translation.m[3][1] = -translation.m[3][1]; translation.m[3][2] = -translation.m[3][2]; justReverted = true; } break; } } diff = rightPos - pos; if (diff.magnitude() <= rightRadius + planet->radius) { newToWorld = toWorld * translation * translation* translation * translation; newPoint = newToWorld.getTranslate().toVector3(); newDiff = newPoint - pos; if (newDiff.magnitude() > diff.magnitude()) { break; } else { if (!justReverted) { genColorz(gShape->rightBoundSphereColor); translation.m[3][0] = -translation.m[3][0]; translation.m[3][1] = -translation.m[3][1]; translation.m[3][2] = -translation.m[3][2]; justReverted = true; } break; } } justReverted = false; } } return true; //cout << "Asteroid New Pos" << endl; //cout << toWorld.m[3][0] << " " << toWorld.m[3][1] << " " << toWorld.m[3][2]<< endl; // }
bool XMLElement::SetVector4(const String& name, const Vector4& value) { return SetAttribute(name, value.ToString()); }
//todo Vector4 operator * (const Transform& t, const Vector4& p) { Vector4 p1; p1[0] = t.v[0][0]*p.get(0) + t.v[0][1]*p.get(1) + t.v[0][2]*p.get(2) + t.v[0][3]*p.get(3); p1[1] = t.v[1][0]*p.get(0) + t.v[1][1]*p.get(1) + t.v[1][2]*p.get(2) + t.v[1][3]*p.get(3); p1[2] = t.v[2][0]*p.get(0) + t.v[2][1]*p.get(1) + t.v[2][2]*p.get(2) + t.v[2][3]*p.get(3); p1[3] = p.get(3); return p1; }
void GizmoSystem::UpdateTools( float deltaTime ) { static Material* pickedToolMaterial; static BasicObject* pickedToolPart = NULL; static Vector3 pickedDirection; static Vector3 applyDirection; static bool isToolPart = false; static float lastDotValue = 0; static GameObject* cameraGO = NULL; int cursorWindow = Systems::Input()->GetCursorWindow(); cameraGO = EditorApp::GetCameraFor( cursorWindow ); if ( _activeTool == E_GizmoTools::Pan ) { if ( Systems::Input()->KeyDown(E_Key::MOUSE_LEFT) ) { uint canvasSlot = EditorApp::GetCanvasSlotFor( cursorWindow ); if ( canvasSlot != -1 && cameraGO != NULL ) { Vector2 cursorDelta = Systems::Input()->CursorDeltaPosition(); cameraGO->GetComponent<Transform>()->TranslateByLocal( Vector3(- cursorDelta.x() * deltaTime, cursorDelta.y() * deltaTime, 0) ); } } return; } if ( Systems::Input()->KeyDownFirstTime(E_Key::MOUSE_LEFT) ) { uint canvasSlot = EditorApp::GetCanvasSlotFor( cursorWindow ); if ( canvasSlot != -1 && cameraGO != NULL ) { Vector2 cursor = Systems::Input()->CursorPosition(); RenderingOptions options(false); RenderingOptions windowOptions = EditorApp::GetRenderingOptionsFor( cursorWindow ); options.gizmoGrid = windowOptions.gizmoGrid; options.gizmoLines = windowOptions.gizmoLines; options.gizmoIcons = windowOptions.gizmoIcons; options.gizmoTools = true; Systems::Rendering()->RenderSceneOffscreen( canvasSlot, E_Renderer::Picking, Systems::Scene()->GetCurrentScene(), cameraGO, options ); Vector4 pixel = Systems::Rendering()->GetPixel( canvasSlot, E_Renderer::Picking, cursor.x(), cursor.y() ); uint pickedIndex = pixel.x(); std::cout << "picked " << pickedIndex << std::endl; for (uint i = 0; i < _toolsParts[_activeTool].size(); ++i) { if ( _toolsParts[_activeTool][i]->uniqueIndex == pickedIndex ) { pickedToolPart = _toolsParts[_activeTool][i]; pickedToolMaterial = pickedToolPart->meshDrawing->GetMaterial(); pickedToolPart->meshDrawing->SetMaterial( _toolsUseMaterial[_activeTool] ); isToolPart = true; pickedDirection = pickedToolPart->transform->GetLocalForward(); switch (_activeTool) { case E_GizmoTools::Translate: applyDirection = pickedDirection; break; case E_GizmoTools::Rotate: applyDirection = pickedToolPart->transform->GetLocalAxisX(); break; case E_GizmoTools::Scale: Quaternion localRotation = pickedToolPart->transform->GetRotationLocal(); applyDirection = MathUtility::ApplyRotation( localRotation, Vector3(0, 0, -1) ); applyDirection.x( (float) ((int) applyDirection.x()) ); applyDirection.y( (float) ((int) applyDirection.y()) ); applyDirection.z( (float) ((int) applyDirection.z()) ); break; } Vector2 screenSize = EditorApp::GetScreenSizeFor( cursorWindow ); Vector3 ray = ObjectUtility::ScreenPointToRay( cursor, cameraGO, screenSize ); lastDotValue = MathUtility::Dot( ray, pickedDirection ); break; } } if ( !isToolPart ) { Systems::Event()->EmitEvent( E_EventType::Object, E_EventName::Object_Selected, Systems::Scene()->Find( pickedIndex ) ); } } } if ( Systems::Input()->KeyUpFirstTime(E_Key::MOUSE_LEFT) ) { if (pickedToolPart != NULL) { pickedToolPart->meshDrawing->SetMaterial( pickedToolMaterial ); } pickedToolPart = NULL; isToolPart = false; } static float translateSpeed = 1.0f; static float rotateSpeed = 40.0f; static float scaleSpeed = 1.0f; if (isToolPart) { int cursorWindow = Systems::Input()->GetCursorWindow(); Vector2 screenSize = EditorApp::GetScreenSizeFor( cursorWindow ); Vector3 ray = ObjectUtility::ScreenPointToRay( Systems::Input()->CursorPosition(), cameraGO, screenSize ); float dotValue = MathUtility::Dot( ray, pickedDirection ); float deltaDotValue = dotValue - lastDotValue; lastDotValue = dotValue; Vector3 objectToCamera = cameraGO->GetComponent<Transform>()->GetPositionWorld() - _pickedGO->GetComponent<Transform>()->GetPositionWorld(); float distanceToCamera = objectToCamera.Length(); Vector3 rotateAxis; switch (_activeTool) { case E_GizmoTools::Translate: _pickedGO->GetComponent<Transform>()->TranslateByWorld( applyDirection * deltaDotValue * translateSpeed * distanceToCamera); break; case E_GizmoTools::Rotate: _pickedGO->GetComponent<Transform>()->RotateByWorld( applyDirection * deltaDotValue * rotateSpeed * distanceToCamera); break; case E_GizmoTools::Scale: if (_toolESpaceSystem == E_SpaceSystem::Local) { _pickedGO->GetComponent<Transform>()->ScaleByConstant( applyDirection * (- deltaDotValue) * scaleSpeed * distanceToCamera); } break; } } // update tools if ( _pickedGO != NULL && cameraGO != NULL ) { // update light _toolsLight->transform->SetRotationWorld( cameraGO->GetComponent<Transform>()->GetRotationWorld() ); // update meshes Vector3 position = _pickedGO->GetComponent<Transform>()->GetPositionWorld(); _tools[_activeTool]->transform->SetPositionWorld( position ); if (_toolESpaceSystem == E_SpaceSystem::Local) { Quaternion rotation = _pickedGO->GetComponent<Transform>()->GetRotationWorld(); _tools[_activeTool]->transform->SetRotationWorld( rotation ); } if (_toolESpaceSystem == E_SpaceSystem::World) { _tools[_activeTool]->transform->SetRotationWorld( Quaternion() ); } Vector3 scaleAmount; if ( cameraGO->GetComponent<Camera>()->GetType() == E_CameraType::Perspective ) { Vector3 cameraPos = cameraGO->GetComponent<Transform>()->GetPositionWorld(); scaleAmount = Vector3(1, 1, 1) * (cameraPos - position).Length() * 0.18f; } else { Vector2 orthoSize = cameraGO->GetComponent<Camera>()->GetOrthoSize(); scaleAmount = Vector3(1, 1, 1) * ((orthoSize.x() + orthoSize.y()) / 2) * 0.14f; } _tools[_activeTool]->transform->SetScaleWorld( scaleAmount ); } }
CMatrix4::CMatrix4(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4) #if 0 : m{ v1.GetX(), v1.GetY(), v1.GetZ(), v1.GetW(), v2.GetX(), v2.GetY(), v2.GetZ(), v2.GetW(), v3.GetX(), v3.GetY(), v3.GetZ(), v3.GetW(), v4.GetX(), v4.GetY(), v4.GetZ(), v4.GetW() } { #else { constexpr std::size_t bytes = sizeof(float) * 4; std::memcpy(static_cast<void*>(&m[0]), static_cast<const float*>(v1), bytes); std::memcpy(static_cast<void*>(&m[4]), static_cast<const float*>(v2), bytes); std::memcpy(static_cast<void*>(&m[8]), static_cast<const float*>(v3), bytes); std::memcpy(static_cast<void*>(&m[12]), static_cast<const float*>(v4), bytes); #endif } CMatrix4::CMatrix4(const Array& m) : m(m) { } void CMatrix4::SetRow(std::int32_t row, const Vector4& v) { HASENPFOTE_ASSERT_MSG((row >= 0) && (row < order), "Row index out of bounds."); m[offset<order>(row, 0)] = v.GetX(); m[offset<order>(row, 1)] = v.GetY(); m[offset<order>(row, 2)] = v.GetZ(); m[offset<order>(row, 3)] = v.GetW(); }
float Vector4::CompProj(const Vector4& argVec1, const Vector4& argVec2) { return Vector4::Dot(argVec1, argVec2) / argVec1.Magnitude(); };
static void Average(void) { float fTexX, fTexY; Vector4 vOffset; Vector4 vTexOffset_256x256[16]; Vector4 vTexOffset_64x64[16]; Vector4 vTexOffset_16x16[16]; Vector4 vTexOffset_4x4[16]; int index = 0; index=0; fTexX = 1.0f/256.0f; fTexY = 1.0f/256.0f; vOffset.Set(-0.5f/64.0f, -0.5f/64.0f, 0.0f, 0.0f); for ( int y=0; y<4; y++ ) { for ( int x=0; x<4; x++ ) { vTexOffset_256x256[index].Set(x*fTexX, y*fTexY, 0.0f, 0.0f); vTexOffset_256x256[index] += vOffset; index++; } } index=0; fTexX = 1.0f/64.0f; fTexY = 1.0f/64.0f; vOffset.Set(-0.5f/16.0f, -0.5f/16.0f, 0.0f, 0.0f); for ( int y=0; y<4; y++ ) { for ( int x=0; x<4; x++ ) { vTexOffset_64x64[index].Set(x*fTexX, y*fTexY, 0.0f, 0.0f); vTexOffset_64x64[index] += vOffset; index++; } } index=0; fTexX = 1.0f/16.0f; fTexY = 1.0f/16.0f; vOffset.Set(-0.5f/4.0f, -0.5f/4.0f, 0.0f, 0.0f); for ( int y=0; y<4; y++ ) { for ( int x=0; x<4; x++ ) { vTexOffset_16x16[index].Set(x*fTexX, y*fTexY, 0.0f, 0.0f); vTexOffset_16x16[index] += vOffset; index++; } } index=0; fTexX = 1.0f/4.0f; fTexY = 1.0f/4.0f; vOffset.Set(-0.5f, -0.5f, 0.0f, 0.0f); for ( int y=0; y<4; y++ ) { for ( int x=0; x<4; x++ ) { vTexOffset_4x4[index].Set(x*fTexX, y*fTexY, 0.0f, 0.0f); vTexOffset_4x4[index] += vOffset; index++; } } ID3D10EffectTechnique *pShader = g_pExposureFX->GetTechniqueByName("Average16Samples"); ID3D10EffectShaderResourceVariable *pImage_var = g_pExposureFX->GetVariableByName("Image0")->AsShaderResource(); ID3D10EffectVectorVariable *pTexOffset_var = g_pExposureFX->GetVariableByName("vTexOffset")->AsVector(); // pShader->GetPassByIndex(0)->Apply(0); // 256x256 -> 64x64 { g_pDevice->OMSetRenderTargets(1, &g_pRTView[DOWNSAMPLED_64x64], NULL); SetViewport(DOWNSAMPLED_64x64); pImage_var->SetResource(g_pSRView[DOWNSAMPLED_256x256]); pTexOffset_var->SetFloatVectorArray( (float *)vTexOffset_256x256, 0, 16); pShader->GetPassByIndex(0)->Apply(0); DrawFullScreenQuad(); } // 64x64 -> 16x16 { g_pDevice->OMSetRenderTargets(1, &g_pRTView[DOWNSAMPLED_16x16], NULL); SetViewport(DOWNSAMPLED_16x16); pImage_var->SetResource(g_pSRView[DOWNSAMPLED_64x64]); pTexOffset_var->SetFloatVectorArray( (float *)vTexOffset_64x64, 0, 16); pShader->GetPassByIndex(0)->Apply(0); DrawFullScreenQuad(); } // 16x16 -> 4x4 { g_pDevice->OMSetRenderTargets(1, &g_pRTView[DOWNSAMPLED_4x4], NULL); SetViewport(DOWNSAMPLED_4x4); pImage_var->SetResource(g_pSRView[DOWNSAMPLED_16x16]); pTexOffset_var->SetFloatVectorArray( (float *)vTexOffset_16x16, 0, 16); pShader->GetPassByIndex(0)->Apply(0); DrawFullScreenQuad(); } // 4x4 -> 1x1 { g_pDevice->OMSetRenderTargets(1, &g_pRTView[LUMINANCE_CURRENT], NULL); SetViewport(LUMINANCE_CURRENT); pImage_var->SetResource(g_pSRView[DOWNSAMPLED_4x4]); pTexOffset_var->SetFloatVectorArray( (float *)vTexOffset_4x4, 0, 16); pShader->GetPassByIndex(0)->Apply(0); DrawFullScreenQuad(); } static int count = 0; count++; }
void ModelRenderer::Render(const Camera* camera) { if(!_renders) return; // ワールド行列設定 Matrix SclMtx, RotMtx, PosMtx, WldMtx, WVPMtx; // 拡縮 D3DXMatrixScaling(&SclMtx, _scale.x, _scale.y, _scale.z); // 回転 : switch-case…クォータニオンか回転行列かXYZ指定か this->Evaluate(); RotMtx = this->_worldRotationMatrix; // 位置 D3DXMatrixTranslation(&PosMtx, _position.x, _position.y, _position.z); GraphicsManager::_device->SetRenderState(D3DRS_CULLMODE, _cullingState); // デバッグ用 //GraphicsManager::_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); // シェーダを使用する場合カメラのビュー行列(0)、プロジェクション行列(1)をワールド行列に合成 WldMtx = SclMtx * RotMtx * PosMtx; WVPMtx = WldMtx * camera->GetMatrix(ViewBehavior::VIEW) * camera->GetMatrix(ViewBehavior::PROJECTION); // カメラの座標をシェーダに使用するための行列変換 Matrix CamMtx = WldMtx * camera->GetMatrix(ViewBehavior::VIEW); D3DXMatrixInverse(&CamMtx, NULL, &CamMtx); auto eye = camera->GetEye(); Vector4 EyePos = Vector4(eye.x, eye.y, eye.z, 1); EyePos.Transform(CamMtx); D3DXVec4Normalize((D3DXVECTOR4*)&EyePos, (D3DXVECTOR4*)&EyePos); // シェーダ設定 _shader->SetTechnique(); // シェーダにワールド * ビュー * プロジェクション行列を渡す _shader->SetWVPMatrix(WVPMtx); // シェーダー特有の値の設定 _shader->ApplyEffect(RotMtx, EyePos); HRESULT hr; // 3D モデルのパーツ分ループして描画 for(size_t i = 0 ; i < _mesh->GetMaterialNumber(); i++) { // テクスチャが存在しない場合のカラー D3DXVECTOR4 color = D3DXVECTOR4(1.0,1.0,1.0,1.0); // 格パーツに対応するテクスチャを設定 // シェーダにテクスチャを渡す if(NULL != _textures[i]) { LPDIRECT3DTEXTURE9 texture = _textures[i]->GetTextureData(); // シェーダにカラーを渡す _shader->SetColor(_colorRGBA); _shader->SetTexture(texture); }else _shader->SetColor(color); // シェーダの使用開始 _shader->BeginShader(); // シェーダのパス設定 _shader->BeginPass(_addsBlend); // パーツの描画 if(SUCCEEDED(GraphicsManager::_device->BeginScene())) { _mesh->GetMesh()->DrawSubset(i); V(GraphicsManager::_device->EndScene()); } // パス終了 _shader->EndPass(); // シェーダ終了 _shader->EndShader(); } }
BoundingBox::BoundingBox(const Vector4& p, float width, float height, float depth) { this->min = Vector4(p.x() - width / 2, p.y() - height / 2, p.z() - depth / 2, 1); this->max = Vector4(p.x() + width / 2, p.y() + height / 2, p.z() + depth / 2, 1); }
void draw(const std::string &s,const Vector2 &pos,const Vector4 &color) { glDepthFunc(GL_ALWAYS); p3d::drawText(s,pos.x(),pos.y(),0,nullptr,nullptr,color.fv()); glDepthFunc(GL_LESS); }
Vector4 Vector4::ProjectionOnto( const Vector4& v ) const { return ( Dot(v) / v.LengthSquared() ) * v; // I assume this is still valid for 4D vectors }
/*static*/ Vector4 Vector4::Normalise(const Vector4& source) { float length = source.GetLength(); return Vector4(source.X / length, source.Y / length, source.Z / length, source.W); }
void PS3_setScanlineBrightness(float bright) { write_log("scanline brightness=%f\n", bright); scanline.setZ(bright); }