void ParticleEmitter3D::PrepareEmitterParameters(Particle * particle, float32 velocity, int32 emitIndex) { Vector3 tempPosition = Vector3(); Matrix4 * worldTransformPtr = GetWorldTransformPtr(); Matrix3 rotationMatrix; rotationMatrix.Identity(); if(worldTransformPtr) { tempPosition = worldTransformPtr->GetTranslationVector(); rotationMatrix = Matrix3(*worldTransformPtr);; } //Vector3 tempPosition = particlesFollow ? Vector3() : position; if (emitterType == EMITTER_POINT) { particle->position = tempPosition; } else if (emitterType == EMITTER_RECT) { float32 rand05_x = (float32)Random::Instance()->RandFloat() - 0.5f; // [-0.5f, 0.5f] float32 rand05_y = (float32)Random::Instance()->RandFloat() - 0.5f; // [-0.5f, 0.5f] float32 rand05_z = (float32)Random::Instance()->RandFloat() - 0.5f; // [-0.5f, 0.5f] Vector3 lineDirection(0, 0, 0); if(size) lineDirection = Vector3(size->GetValue(time).x * rand05_x, size->GetValue(time).y * rand05_y, size->GetValue(time).z * rand05_z); //particle->position = tempPosition + lineDirection; particle->position = tempPosition + TransformPerserveLength(lineDirection, rotationMatrix); } else if ((emitterType == EMITTER_ONCIRCLE_VOLUME) || (emitterType == EMITTER_ONCIRCLE_EDGES)) { CalculateParticlePositionForCircle(particle, tempPosition, rotationMatrix); } if (emitterType == EMITTER_SHOCKWAVE) { // For "Shockwave" emitters the calculation is different. PrepareEmitterParametersShockwave(particle, velocity, emitIndex, tempPosition, rotationMatrix); } else { PrepareEmitterParametersGeneric(particle, velocity, emitIndex, tempPosition, rotationMatrix); } if(worldTransformPtr) { Matrix4 newTransform = *worldTransformPtr; newTransform._30 = newTransform._31 = newTransform._32 = 0; float32 speedLength = particle->speed.Length(); particle->speed = particle->speed*newTransform; float32 speedLengthAfter = particle->speed.Length(); if (speedLengthAfter) particle->speed*=speedLength/speedLengthAfter; } }
//Concat a matrix and a vector Vector2 operator*(const Matrix3 &lhs, const Vector2 &rhs) { Matrix3 temp; temp.Identity(); Vector2 result; for(int y = 0; y < 2; ++y) { temp.m[0][y] = lhs.m[0][y]*rhs.x + lhs.m[1][y]*rhs.y + lhs.m[y][2]; } result.x = temp.m[0][0]; result.y = temp.m[0][1]; return result; }
void Opengl2dPainter::drawBegin(Pen& pen, Matrix3& matrix) { OpenglContext oglcontext(_pPimpl->hdc, _pPimpl->hrc); if (pen.color().a < 255) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE); } glColor4ub( pen.color().r, pen.color().g, pen.color().b, pen.color().a ); _pPimpl->pen = pen; _pPimpl->localMatrix = matrix; glLineWidth( _pPimpl->pen.width()); if (pen.linestyle() != 0xFFFF) { glEnable(GL_LINE_STIPPLE); glLineStipple(1, pen.linestyle()); } Matrix3 selectedMovingMatrix; selectedMovingMatrix.Identity(); // apply matrix Matrix3 m3 = _pPimpl->worldMatrix * selectedMovingMatrix * _pPimpl->localMatrix; FLOAT m[4*4] = {0, }; m[0] = m3.element[0]; m[1] = m3.element[3]; m[2] = 0.0f; m[3] = 0.0f; m[4] = m3.element[1]; m[5] = m3.element[4]; m[6] = 0.0f; m[7] = 0.0f; m[8] = 0.0f; m[9] = 0.0f; m[10] = 1.0f; m[11] = 0.0f; m[12] = m3.element[2]; m[13] = m3.element[5]; m[14] = 0.0f; m[15] = 1.0f; glLoadMatrixf(m); }
ObjectRenderer::pShapeStruct ObjectRenderer::LoadShape(const pXmlTree tree){ if(tree==NULL) return NULL; REALTYPE *array; pXmlTree tmpTree = tree; pShapeStruct shape = NULL; if((tmpTree->GetName()=="Shape")){ gLOG.Append("Setting up Shape : %s",tmpTree->GetData().c_str()); gLOG.SetDeltaIndent(2); int size; Matrix3 scale; scale.Identity(); if(tmpTree->Find("Scale")){ size=tmpTree->GetArray("Scale",&array); if(size==3){ scale.Diag(Vector3(array)); scale.RefNoCheck(0,0) = array[0]; scale.RefNoCheck(1,1) = array[1]; scale.RefNoCheck(2,2) = array[2]; }else{ gLOG.Append("Error: Bad <Scale> array size (should be 3)"); } } string params = tmpTree->Get("Params",string("")); vector<string> ptokens = Tokenize(RemoveSpaces(params)); shape = new ShapeStruct; shape->shape = new GL3DObject(); shape->strShapeName = tmpTree->GetData(); shape->scale[0] = scale.At(0,0); shape->scale[1] = scale.At(1,1); shape->scale[2] = scale.At(2,2); if(tmpTree->GetData().length()==0){ gLOG.Append("Error: No shape specified"); }else if(tmpTree->GetData() == "Cube"){ shape->shape->GenerateCube(); }else if(tmpTree->GetData() == "Cylinder"){ if(ptokens.size()>=1){ shape->shape->GenerateCylinder(atoi(ptokens[0].c_str())); }else{ shape->shape->GenerateCylinder(16); } }else if(tmpTree->GetData() == "Sphere"){ if(ptokens.size()>=2){ shape->shape->GenerateSphere(atoi(ptokens[0].c_str()),atoi(ptokens[1].c_str())); }else{ shape->shape->GenerateSphere(16,12); } }else if(tmpTree->GetData() == "Capsule"){ if(ptokens.size()==1){ shape->shape->GenerateCapsule(atof(ptokens[0].c_str()),16,6); }else if(ptokens.size()>=3){ shape->shape->GenerateCapsule(atof(ptokens[0].c_str()),atoi(ptokens[1].c_str()),atoi(ptokens[2].c_str())); }else{ shape->shape->GenerateCapsule(0.5*(scale.RefNoCheck(0,0)+scale.RefNoCheck(1,1)),16,6); } }else if(tmpTree->GetData() == "HeightField"){ if(tmpTree->Find("DataFile")){ string filename = tmpTree->GetBasePath()+string("/")+tmpTree->Find("DataFile")->GetData(); Matrix hf; if(hf.Load(filename.c_str())){ shape->shape->GenerateHeightField(hf,1,1,1); }else{ delete shape->shape; shape->shape=NULL; gLOG.Append("Error: Height field file %s failed to open",filename.c_str()); } }else{ delete shape->shape; shape->shape=NULL; gLOG.Append("Error: Height field: No <DataFile> specified..."); } /*if(ptokens.size()==1){ shape->shape->GenerateCapsule(atof(ptokens[0].c_str()),16,6); }else if(ptokens.size()>=3){ shape->shape->GenerateCapsule(atof(ptokens[0].c_str()),atoi(ptokens[1].c_str()),atoi(ptokens[2].c_str())); }else{ shape->shape->GenerateCapsule(0.5*(scale.RefNoCheck(0,0)+scale.RefNoCheck(1,1)),16,6); }*/ }else{ bool bShapeFound = false; string shapeFile; if(!bShapeFound){ shapeFile = tmpTree->GetData(); bShapeFound = FileFinder::Find(shapeFile); if(bShapeFound) shapeFile = FileFinder::GetString(); } if(!bShapeFound){ shapeFile = mBasePath+"/"+tmpTree->GetData(); bShapeFound = FileFinder::Find(shapeFile); if(bShapeFound) shapeFile = FileFinder::GetString(); } if(!bShapeFound){ shapeFile = tmpTree->GetBasePath()+"/"+tmpTree->GetData(); bShapeFound = FileFinder::Find(shapeFile); if(bShapeFound) shapeFile = FileFinder::GetString(); } if(bShapeFound){ if(!shape->shape->LoadFromObjFile(shapeFile.c_str())){ delete shape->shape; shape->shape=NULL; gLOG.Append("Error: Unable to load shape file: %s",shapeFile.c_str()); } }else{ gLOG.Append("Error: Unable to find shape file: %s",shapeFile.c_str()); } } if(tmpTree->Find("Origin")){ size=tmpTree->GetArray("Origin",&array); if(size==3){ shape->refShape.SetOrigin().Set(array); }else{ shape->refShape.SetOrigin().Zero(); gLOG.Append("Error: Bad <Origin> array size (should be 3)"); } }else{ shape->refShape.SetOrigin().Zero(); gLOG.Append("Warning: No <Origin> defined"); } if(tmpTree->Find("Orient")){ size=tmpTree->GetArray("Orient",&array); if(size==9){ shape->refShape.SetOrient().Set(array); shape->refShape.SetOrient().Normalize(); }else if(size==3){ shape->refShape.SetOrient().SRotationV(Vector3(array)); }else{ shape->refShape.SetOrient().Identity(); gLOG.Append("Error: Bad <Orient> array size (should be 3(axis*angle) or 9(full rotation matrix))"); } }else{ shape->refShape.SetOrient().Identity(); gLOG.Append("Warning: No <Orient> defined"); } shape->refShape.Update(); if(tmpTree->Find("Color")){ size=tmpTree->GetArray("Color",&array); if(size==3){ memcpy(shape->color,array,3*sizeof(REALTYPE)); shape->color[3] = 1.0; }else if(size==4){ memcpy(shape->color,array,4*sizeof(REALTYPE)); }else{ shape->color[0] = 1.0; shape->color[1] = 1.0; shape->color[2] = 1.0; shape->color[3] = 1.0; gLOG.Append("Error: Bad <Color> array size (should be 3 or 4)"); } }else{ shape->color[0] = 1.0; shape->color[1] = 1.0; shape->color[2] = 1.0; shape->color[3] = 1.0; gLOG.Append("Warning: No <Color> defined"); } if(tmpTree->Find("DoubleFace")){ shape->culling = tmpTree->Get("DoubleFace",false); } else { shape->culling = false; } if(shape->shape!=NULL){ shape->shape->Transform(scale); shape->shape->Transform(shape->refShape.GetHMatrix()); /* pXmlTree tmpShadowTree; if((tmpShadowTree=tmpTree->Find("Shadow"))!=NULL){ string params = tmpShadowTree->Get("Params",string("")); vector<string> ptokens = Tokenize(RemoveSpaces(params)); GL3DObject *shadow = new GL3DObject(); if(tmpShadowTree->GetData() == "Cube"){ shadow->GenerateCube(); }else if(tmpShadowTree->GetData() == "Cylinder"){ if(ptokens.size()>=1){ shadow->GenerateCylinder(atoi(ptokens[0].c_str())); }else{ shadow->GenerateCylinder(8); } }else if(tmpShadowTree->GetData() == "Sphere"){ if(ptokens.size()>=2){ shadow->GenerateSphere(atoi(ptokens[0].c_str()),atoi(ptokens[1].c_str())); }else{ shadow->GenerateSphere(4,4); } }else if(tmpShadowTree->GetData() == "Clone"){ delete shadow; shadow=shape->shape->Clone(); }else{ if(!shadow->LoadFromObjFile(tmpShadowTree->GetData().c_str(),true)){ delete shadow; shadow=NULL; } } if(shadow!=NULL){ shadow->Transform(shape->refShape.GetHMatrix()); if(tmpShadowTree->Find("Origin")){ Vector3 origin; origin.Set(Vector(array,tmpShadowTree->GetArray("Origin",&array))); shadow->AddOffset(origin); } if(tmpShadowTree->Find("Orient")){ Matrix3 orient; orient.Set(Matrix(array,tmpShadowTree->GetArray("Orient",&array)/3,3)); shadow->Transform(orient); } shape->shape->SetShadow(shadow); } } */ } gLOG.SetDeltaIndent(-2); } return shape; }