void ModelGroup::update(Storm &storm, const VC3 &position) { QUAT quat; //quat.MakeFromAngles(0, rotation, 0); quat = frozenbyte::editor::getRotation(rotationEul); MAT tm; tm.CreateRotationMatrix(quat); for(int i = 0; i < int(models.size()); ++i) { if(!models[i]) continue; const GroupList::Instance &instance = objectGroup.instances[i]; VC3 pos = instance.position; tm.RotateVector(pos); pos += position; pos.y = storm.getHeight(VC2(pos.x, pos.z)) + heightOffset; pos.y += objectGroup.instances[i].position.y; models[i]->SetPosition(pos); VC3 angles = getRotation(storm, i); quat = frozenbyte::editor::getRotation(angles); //QUAT q; //q.MakeFromAngles(0, rotation, 0); //quat = quat * q; models[i]->SetRotation(quat); } }
void calculateValues() { MAT tm; tm.CreateRotationMatrix(rotation); // A bit optimized version, use base vectors directly normal.x = tm.Get(8); normal.y = tm.Get(9); normal.z = tm.Get(10); VC3 biasNormal = normal; biasNormal *= .07f; VC3 right(tm.Get(0), tm.Get(1), tm.Get(2)); VC3 up(tm.Get(4), tm.Get(5), tm.Get(6)); right *= .5f * size.x; up *= .5f * size.y; assert(fabsf(up.GetDotWith(right)) < 0.0001f); vertices[0] = position; vertices[0] -= right; vertices[0] -= up; vertices[0] += biasNormal; vertices[1] = position; vertices[1] -= right; vertices[1] += up; vertices[1] += biasNormal; vertices[2] = position; vertices[2] += right; vertices[2] -= up; vertices[2] += biasNormal; vertices[3] = position; vertices[3] += right; vertices[3] += up; vertices[3] += biasNormal; COL finalColor = light; finalColor.Clamp(); vertexColor = finalColor.GetAsD3DCompatibleARGB() & 0x00FFFFFF; vertexColor |= alpha << 24; if(entity) entity->setRadius(getRadius()); }
VC3 getSunDirection() const { float yAngle = getSliderValue(dialog, IDC_SUN_YANGLE) / 180.f * PI; float xAngle = -getSliderValue(dialog, IDC_SUN_XANGLE) / 180.f * PI; float strength = getSliderValue(dialog, IDC_SUN_STRENGTH) / 400.f; QUAT q; q.MakeFromAngles(xAngle, yAngle); q.Normalize(); MAT tm; tm.CreateRotationMatrix(q); VC3 result(0, 0, strength); tm.RotateVector(result); return result; }
int Storm3D_ParticleSystem::QuadArray::lock(VXFORMAT_PART *pointer, int particleOffset, Storm3D_Scene *scene) { m_partOffset = particleOffset; pointer += particleOffset * 4; VXFORMAT_PART *vp = pointer; float frameWidth = 0.0f; float frameHeight = 0.0f; if(m_animInfo.numFrames > 1) { frameWidth = 1.0f / m_animInfo.textureUSubDivs; frameHeight = 1.0f / m_animInfo.textureVSubDivs; } BYTE *verts = (BYTE*)&vp[0].position; BYTE *uvs = (BYTE*)&vp[0].texcoords; BYTE *colors = (BYTE*)&vp[0].color; DWORD stride = sizeof(VXFORMAT_PART); D3DXMATRIX mv = scene->camera.GetViewMatrix(); DWORD c0 = 0; // Up rotation MAT view(scene->camera.GetViewMatrix()); VC3 worldUp(0, 1.f, 0); view.RotateVector(worldUp); QUAT q; rotateToward(worldUp, VC3(0, 0, 1.f), q); MAT g; g.CreateRotationMatrix(q); for(int i = 0; i < m_numParts; i++) { Storm3D_PointParticle& p = m_parts[i]; float sa = sinf(p.angle); float ca = cosf(p.angle); float hsize = 0.5f*p.size; float x1,y1,x2,y2,x3,y3,x4,y4; quad_util::rotatePointFast(x1, y1, -hsize, hsize, ca, sa); quad_util::rotatePointFast(x2, y2, hsize, hsize, ca, sa); quad_util::rotatePointFast(x3, y3, -hsize, -hsize, ca, sa); quad_util::rotatePointFast(x4, y4, hsize, -hsize, ca, sa); VC3 v; v.x = p.position.x * mv.m[0][0] + p.position.y * mv.m[1][0] + p.position.z * mv.m[2][0] + mv.m[3][0]; v.y = p.position.x * mv.m[0][1] + p.position.y * mv.m[1][1] + p.position.z * mv.m[2][1] + mv.m[3][1]; v.z = p.position.x * mv.m[0][2] + p.position.y * mv.m[1][2] + p.position.z * mv.m[2][2] + mv.m[3][2]; VC3 v1(x1, y1, 0); VC3 v2(x2, y2, 0); VC3 v3(x3, y3, 0); VC3 v4(x4, y4, 0); if(faceUp) { g.RotateVector(v1); g.RotateVector(v2); g.RotateVector(v3); g.RotateVector(v4); } v1 += v; v2 += v; v3 += v; v4 += v; /* VC3 v1(v.x + x1, v.y + y1, v.z); VC3 v2(v.x + x2, v.y + y2, v.z); VC3 v3(v.x + x3, v.y + y3, v.z); VC3 v4(v.x + x4, v.y + y4, v.z); { v1 -= v; g.RotateVector(v1); v1 += v; v2 -= v; g.RotateVector(v2); v2 += v; v3 -= v; g.RotateVector(v3); v3 += v; v4 -= v; g.RotateVector(v4); v4 += v; } */ *((Vector*)verts) = v1; verts += stride; *((Vector*)verts) = v2; verts += stride; *((Vector*)verts) = v3; verts += stride; *((Vector*)verts) = v4; verts += stride; // Fill texturecoords if(m_animInfo.numFrames > 1) { int frame = (int)p.frame % m_animInfo.numFrames; int col = frame % m_animInfo.textureUSubDivs; int row = frame / m_animInfo.textureUSubDivs; float tx = frameWidth * (float)col; float ty = frameHeight * (float)row; *((float*)uvs) = tx; uvs += 4; *((float*)uvs) = ty; uvs += (stride - 4); *((float*)uvs) = tx + frameWidth; uvs += 4; *((float*)uvs) = ty; uvs += (stride - 4); *((float*)uvs) = tx; uvs += 4; *((float*)uvs) = ty + frameHeight; uvs += (stride - 4); *((float*)uvs) = tx + frameWidth; uvs += 4; *((float*)uvs) = ty + frameHeight; uvs += (stride - 4); } else { *((float*)uvs) = 0.0f; uvs += 4; *((float*)uvs) = 0.0f; uvs += (stride - 4); *((float*)uvs) = 1.0f; uvs += 4; *((float*)uvs) = 0.0f; uvs += (stride - 4); *((float*)uvs) = 0.0f; uvs += 4; *((float*)uvs) = 1.0f; uvs += (stride - 4); *((float*)uvs) = 1.0f; uvs += 4; *((float*)uvs) = 1.0f; uvs += (stride - 4); } c0 = (((DWORD)(p.alpha * 255.0f) &0xff) << 24) | (((DWORD)(factor.r * p.color.r * 255.0f) &0xff) << 16) | (((DWORD)(factor.g * p.color.g * 255.0f) &0xff) << 8) | (((DWORD)(factor.b * p.color.b * 255.0f) &0xff) ); *((DWORD*)colors) = c0; colors += stride; *((DWORD*)colors) = c0; colors += stride; *((DWORD*)colors) = c0; colors += stride; *((DWORD*)colors) = c0; colors += stride; } return m_numParts; }
//------------------------------------------------------------------ // Storm3D_Material::Apply // Applies material. Use pass parameter to tell with pass to // render. Start with pass=0, and increase it until this routine // returns false. (=all passes rendered) // // Returns: // false = this was last pass // true = new pass must be rendered //------------------------------------------------------------------ bool Storm3D_Material::Apply(Storm3D_Scene *scene,int pass,DWORD fvf,D3DMATRIX *mtx) { /* Basic config: All textures = NULL Stage0: colorop = modulate colorarg1 = texture colorarg2 = diffuse alphaop = disable texturetransformflags = disable texcoordindex = 0 Stage1-3: colorarg1 = texture colorarg2 = current alphaop = disable texturetransformflags = disable texcoordindex = 0 After rendering material's UnApply() is called, and it returns these states, if it changes them. */ // BETA: UnApply() all (very slow!) Storm3D2->device.SetRenderState(D3DRS_LIGHTING,TRUE); Storm3D2->device.SetRenderState(D3DRS_ALPHATESTENABLE,FALSE); Storm3D2->device.SetTexture(0,NULL); Storm3D2->device.SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); Storm3D2->device.SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE); Storm3D2->device.SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE); Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_DISABLE); Storm3D2->device.SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0); Storm3D2->device.SetTextureStageState(0,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE); // FixMe: // Setting this causes debug runtime to halt (set only to supported stages) //for (int i=1;i<3;i++) for (int i=0;i<2;i++) { Storm3D2->device.SetTexture(i,NULL); Storm3D2->device.SetTextureStageState(i,D3DTSS_COLORARG1,D3DTA_TEXTURE); Storm3D2->device.SetTextureStageState(i,D3DTSS_COLORARG2,D3DTA_CURRENT); Storm3D2->device.SetTextureStageState(i,D3DTSS_ALPHAOP,D3DTOP_DISABLE); Storm3D2->device.SetTextureStageState(i,D3DTSS_TEXCOORDINDEX,i); Storm3D2->device.SetTextureStageState(i,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE); } // Animate textures if (texture_base) texture_base->texture->AnimateVideo(); if (texture_base2) texture_base2->texture->AnimateVideo(); if (texture_reflection) texture_reflection->texture->AnimateVideo(); if (texture_bump) texture_bump->texture->AnimateVideo(); // The superb if(TM) multitexturing (no effects/techniques needed anymore!) // This routine is much faster than DX8-effect system (and bugfree also;)... if (multitexture_type==MTYPE_COLORONLY) // COL only { // Set stages (color only) //Storm3D2->device.SetTexture(0,NULL); // psd: assume lightmap if base2 defined if(texture_base2) { texture_base2->texture->Apply(0); Storm3D2->device.SetTextureStageState(0,D3DTSS_COLOROP,texture_base2->GetDX8MultitexBlendingOp()); } else { Storm3D2->device.SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1); Storm3D2->device.SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_DIFFUSE); Storm3D2->device.SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); } } else if (multitexture_type==MTYPE_TEXTURE) // Base { // Set stage (base) texture_base->texture->Apply(0); // Disable last stage Storm3D2->device.SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); } else if (multitexture_type==MTYPE_DUALTEX) // Base+Base2 { // Set stage (base) texture_base->texture->Apply(0); // Set stage (base2) texture_base2->texture->Apply(1); Storm3D2->device.SetTextureStageState(1,D3DTSS_COLOROP,texture_base2->GetDX8MultitexBlendingOp()); // Disable last stage Storm3D2->device.SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_DISABLE); } else if (multitexture_type==MTYPE_REF) // Reflection { // Set stage (reflection) texture_reflection->texture->Apply(0); // Reflection texture (or projective?) if (texture_reflection->texcoord_gen==TEX_GEN_REFLECTION) { Storm3D2->device.SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); // Correct number of texturecoordinates if (texture_reflection->texture->IsCube()) Storm3D2->device.SetTextureStageState(0,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3); else Storm3D2->device.SetTextureStageState(0,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2); // Rotate the reflection VC3 camdir=scene->camera.GetDirection(); float angle_y=VC2(camdir.x,camdir.z).CalculateAngle(); float angle_x=VC2(VC2(camdir.x,camdir.z).GetLength(),camdir.y).CalculateAngle(); MAT mat; mat.CreateRotationMatrix(QUAT(-angle_x,-angle_y,0)); if (!texture_reflection->texture->IsCube()) { // Fix reflection (v2.3) float mt[16]= { 0.5, 0, 0, 0, 0, -0.5, 0, 0, 0, 0, 1, 0, 0.5, 0.5, 0, 1 }; MAT mat2(mt); mat.Multiply(mat2); // Flip texture upside down //mat.Multiply(MAT(VC3(1,-1,1))); } // Set texture rotation matrix D3DMATRIX dxmat; mat.GetAsD3DCompatible4x4((float*)&dxmat); Storm3D2->device.SetTransform(D3DTS_TEXTURE0,&dxmat); } else // Projective texture { // Create matrix, tu=(0.5+0.87*x)/z, tv=(0.5-0.87*y)/z D3DXMATRIX mat; mat._11=0.866f;mat._12=0.0f;mat._13=0.0f; mat._21=0.0f;mat._22=-0.866f;mat._23=0.0f; mat._31=0.5f;mat._32=0.5f;mat._33=1.0f; mat._41=0.0f;mat._42=0.0f;mat._43=0.0f; // If it's mirror negate _11 if (texture_reflection->texcoord_gen==TEX_GEN_PROJECTED_MIRROR) mat._11*=-1; Storm3D2->device.SetTransform(D3DTS_TEXTURE0,&mat); Storm3D2->device.SetTextureStageState(0,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3|D3DTTFF_PROJECTED); Storm3D2->device.SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION); } // Disable last stage Storm3D2->device.SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_DISABLE); } else if (multitexture_type==MTYPE_TEX_REF) // Base+Reflection { // Set stage (base) texture_base->texture->Apply(0); // Set stage (reflection) texture_reflection->texture->Apply(1); Storm3D2->device.SetTextureStageState(1,D3DTSS_COLOROP,texture_reflection->GetDX8MultitexBlendingOp()); // Reflection texture (or projective?) if (texture_reflection->texcoord_gen==TEX_GEN_REFLECTION) { Storm3D2->device.SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); // Correct number of texturecoordinates if (texture_reflection->texture->IsCube()) Storm3D2->device.SetTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3); else Storm3D2->device.SetTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2); // Rotate the reflection VC3 camdir=scene->camera.GetDirection(); float angle_y=VC2(camdir.x,camdir.z).CalculateAngle(); float angle_x=VC2(VC2(camdir.x,camdir.z).GetLength(),camdir.y).CalculateAngle(); MAT mat; mat.CreateRotationMatrix(QUAT(-angle_x,-angle_y,0)); if (!texture_reflection->texture->IsCube()) { // Fix reflection (v2.3) float mt[16]= { 0.5, 0, 0, 0, 0, -0.5, 0, 0, 0, 0, 1, 0, 0.5, 0.5, 0, 1 }; MAT mat2(mt); mat.Multiply(mat2); } // Set texture rotation matrix D3DMATRIX dxmat; mat.GetAsD3DCompatible4x4((float*)&dxmat); Storm3D2->device.SetTransform(D3DTS_TEXTURE1,&dxmat); } else // Projective mirror texture { // Create matrix, tu=(0.5+0.87*x)/z, tv=(0.5-0.87*y)/z D3DXMATRIX mat; mat._11=0.866f;mat._12=0.0f;mat._13=0.0f; mat._21=0.0f;mat._22=-0.866f;mat._23=0.0f; mat._31=0.5f;mat._32=0.5f;mat._33=1.0f; mat._41=0.0f;mat._42=0.0f;mat._43=0.0f; // If it's mirror negate _11 if (texture_reflection->texcoord_gen==TEX_GEN_PROJECTED_MIRROR) mat._11*=-1; Storm3D2->device.SetTransform(D3DTS_TEXTURE1,&mat); Storm3D2->device.SetTextureStageState(1,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3|D3DTTFF_PROJECTED); Storm3D2->device.SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION); } // Disable last stage Storm3D2->device.SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_DISABLE); } // Setup material D3DMATERIAL9 mat; // Set diffuse mat.Diffuse.r=mat.Ambient.r=color.r; mat.Diffuse.g=mat.Ambient.g=color.g; mat.Diffuse.b=mat.Ambient.b=color.b; mat.Diffuse.a=mat.Ambient.a=0; // Set self.illum mat.Emissive.r=self_illum.r; mat.Emissive.g=self_illum.g; mat.Emissive.b=self_illum.b; mat.Emissive.a=0; // Set specular mat.Specular.r=specular.r; mat.Specular.g=specular.g; mat.Specular.b=specular.b; mat.Specular.a=0; mat.Power=specular_sharpness; // Set specular on only if it's used if ((specular_sharpness>1)&& ((specular.r>0.01f)||(specular.g>0.01f)||(specular.b>0.01f))) { Storm3D2->device.SetRenderState(D3DRS_SPECULARENABLE,TRUE); } else Storm3D2->device.SetRenderState(D3DRS_SPECULARENABLE,FALSE); // Set 2sided // if (doublesided) Storm3D2->device.SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); // else Storm3D2->device.SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW); // Set wireframe if (wireframe) Storm3D2->device.SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); else Storm3D2->device.SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID); // BETA!!! //Storm3D2->device.SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME); // Set alphablending if (alphablend_type==ATYPE_NONE) { Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,TRUE); Storm3D2->device.SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); } else if (alphablend_type==ATYPE_USE_TRANSPARENCY) { if (transparency>0.001f) { mat.Diffuse.a=1.0f-transparency; Storm3D2->device.SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); Storm3D2->device.SetRenderState(D3DRS_ALPHATESTENABLE,FALSE); Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,FALSE); Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_DIFFUSE); Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); Storm3D2->device.SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); Storm3D2->device.SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); } else { Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,TRUE); Storm3D2->device.SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); } } else if (alphablend_type==ATYPE_USE_TEXTRANSPARENCY || alphablend_type==IStorm3D_Material::ATYPE_USE_ALPHATEST) { mat.Diffuse.a=1.0f-transparency; Storm3D2->device.SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); if(alphablend_type==IStorm3D_Material::ATYPE_USE_ALPHATEST) Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,TRUE); else Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,FALSE); if ((multitexture_type==MTYPE_DOT3_TEX)||(multitexture_type==MTYPE_DOT3_REF)) { // Stage 1 alphamap (no diffuse) Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE); Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2); Storm3D2->device.SetTextureStageState(1,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); Storm3D2->device.SetTextureStageState(1,D3DTSS_ALPHAARG2,D3DTA_CURRENT); Storm3D2->device.SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1); } else { // Stage 0 alphamap * diffuse Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE); Storm3D2->device.SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE); } Storm3D2->device.SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); Storm3D2->device.SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); Storm3D2->device.SetRenderState(D3DRS_ALPHAREF,(DWORD)0x00000001); Storm3D2->device.SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL); Storm3D2->device.SetRenderState(D3DRS_ALPHATESTENABLE,TRUE); } else if (alphablend_type==ATYPE_ADD) { Storm3D2->device.SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); Storm3D2->device.SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); Storm3D2->device.SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE); Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,FALSE); } else if (alphablend_type==ATYPE_MUL) { Storm3D2->device.SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); Storm3D2->device.SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ZERO); Storm3D2->device.SetRenderState(D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR); Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,FALSE); } else if (alphablend_type==ATYPE_MUL2X) { Storm3D2->device.SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); Storm3D2->device.SetRenderState(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR); Storm3D2->device.SetRenderState(D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR); Storm3D2->device.SetRenderState(D3DRS_ZWRITEENABLE,FALSE); } // Use this material Storm3D2->device.SetMaterial(&mat); /* PSD // Apply shader if (!ApplyShaderIfAvailable(scene,mtx)) Storm3D2->device.SetVertexShader(fvf); */ // Set active material Storm3D2->active_material=this; return false; }