void MScene::drawObjectsBehaviors(void) { unsigned int i; unsigned int oSize = getObjectsNumber(); for(i=0; i<oSize; i++) { MObject3d * object = getObjectByIndex(i); if(! object->isActive()) continue; object->drawBehaviors(); } }
void MFixedRenderer::updateVisibility(MScene * scene, MOCamera * camera) { // make frustum camera->getFrustum()->makeVolume(camera); // compute object visibility unsigned int i; unsigned int oSize = scene->getObjectsNumber(); for(i=0; i<oSize; i++) { MObject3d * object = scene->getObjectByIndex(i); if(object->isActive()) object->updateVisibility(camera); } }
void MScene::update(void) { // update objects unsigned int i; unsigned int oSize = getObjectsNumber(); for(i=0; i<oSize; i++) { MObject3d * object = getObjectByIndex(i); if(object->isActive()) object->update(); } // update current frame m_currentFrame++; }
void MScene::prepareCollisionShape(MOEntity * entity) { MPhysicsContext * physics = MEngine::getInstance()->getPhysicsContext(); MPhysicsProperties * phyProps = entity->getPhysicsProperties(); if(! phyProps) return; unsigned int shapeId = 0; if(createShape(entity, phyProps, &shapeId)) { // has physics child bool hasPhysicsChild = false; unsigned int o; unsigned int oSize = entity->getChildsNumber(); for(o=0; o<oSize; o++) { MObject3d * childObject = entity->getChild(o); if(childObject->getType() == M_OBJECT3D_ENTITY) { MOEntity * childEntity = (MOEntity*)childObject; MPhysicsProperties * childPhyProps = childEntity->getPhysicsProperties(); if(childPhyProps) { if(! childPhyProps->isGhost()) { hasPhysicsChild = true; break; } } } } // create multi shape if(hasPhysicsChild) { unsigned int subShapeId = shapeId; physics->createMultiShape(&shapeId); physics->addChildShape(shapeId, subShapeId, MVector3(), MQuaternion()); } phyProps->setShapeId(shapeId); } }
void MGame::update(void) { MEngine * engine = MEngine::getInstance(); // run script if(engine->getScriptContext()) engine->getScriptContext()->callFunction("onSceneUpdate"); // get level MLevel * level = MEngine::getInstance()->getLevel(); if(! level) return; // get current scene MScene * scene = level->getCurrentScene(); if(! scene) return; // update behaviors unsigned int i; unsigned int oSize = scene->getObjectsNumber(); for(i=0; i<oSize; i++) { MObject3d * object = scene->getObjectByIndex(i); if(! object->isActive()) continue; object->updateBehaviors(); } // update scene scene->update(); // update physics scene->updatePhysics(); // update objects matrices scene->updateObjectsMatrices(); // flush input engine->getInputContext()->flush(); }
void MObject3d::computeChildsMatrices(void) { unsigned int i; unsigned int childSize = m_childs.size(); MObject3d * childObject = NULL; for(i=0; i<childSize; i++) // for all childs { childObject = m_childs[i]; // compute parenting (parent matrix * child local matrix) if(m_needToUpdate || childObject->needToUpdate()) { childObject->computeLocalMatrix(); childObject->m_matrix = m_matrix * childObject->m_matrix; childObject->m_needToUpdate = true; } childObject->computeChildsMatrices(); } m_needToUpdate = false; }
void MScene::updateObjectsMatrices(void) { unsigned int i; unsigned int oSize = getObjectsNumber(); for(i=0; i<oSize; i++) { MObject3d * object = getObjectByIndex(i); if(! object->isActive()) continue; if(! object->hasParent()) { if(object->needToUpdate()) object->computeLocalMatrix(); object->computeChildsMatrices(); } } }
// Mesh bin export bool exportMeshBin(const char * filename, MMesh * mesh) { int version = 2; char rep[256]; bool state; // create file MFile * file = M_fopen(filename, "wb"); if(! file) { printf("Error : can't create file %s\n", filename); return false; } // get file directory getRepertory(rep, filename); // header M_fwrite(M_MESH_HEADER, sizeof(char), 8, file); // version M_fwrite(&version, sizeof(int), 1, file); // Animation { // anim refs MArmatureAnimRef * armatureAnimRef = mesh->getArmatureAnimRef(); MTexturesAnimRef * texturesAnimRef = mesh->getTexturesAnimRef(); MMaterialsAnimRef * materialsAnimRef = mesh->getMaterialsAnimRef(); // armature anim ref writeDataRef(file, armatureAnimRef, rep); // textures anim ref writeDataRef(file, texturesAnimRef, rep); // materials anim ref writeDataRef(file, materialsAnimRef, rep); // anims ranges unsigned int animsRangesNumber = mesh->getAnimsRangesNumber(); MAnimRange * animsRanges = mesh->getAnimsRanges(); M_fwrite(&animsRangesNumber, sizeof(int), 1, file); if(animsRangesNumber > 0) M_fwrite(animsRanges, sizeof(MAnimRange), animsRangesNumber, file); } // Textures { unsigned int t, texturesNumber = mesh->getTexturesNumber(); M_fwrite(&texturesNumber, sizeof(int), 1, file); for(t=0; t<texturesNumber; t++) { MTexture * texture = mesh->getTexture(t); MTextureRef * textureRef = texture->getTextureRef(); M_TEX_GEN_MODES genMode = texture->getGenMode(); M_WRAP_MODES UWrapMode = texture->getUWrapMode(); M_WRAP_MODES VWrapMode = texture->getVWrapMode(); MVector2 texTranslate = texture->getTexTranslate(); MVector2 texScale = texture->getTexScale(); float texRotate = texture->getTexRotate(); // texture ref writeDataRef(file, textureRef, rep); if(textureRef) { bool mipmap = textureRef->isMipmapEnabled(); M_fwrite(&mipmap, sizeof(bool), 1, file); } // data M_fwrite(&genMode, sizeof(M_TEX_GEN_MODES), 1, file); M_fwrite(&UWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&VWrapMode, sizeof(M_WRAP_MODES), 1, file); M_fwrite(&texTranslate, sizeof(MVector2), 1, file); M_fwrite(&texScale, sizeof(MVector2), 1, file); M_fwrite(&texRotate, sizeof(float), 1, file); } } // Materials { unsigned int m, materialsNumber = mesh->getMaterialsNumber(); M_fwrite(&materialsNumber, sizeof(int), 1, file); for(m=0; m<materialsNumber; m++) { MMaterial * material = mesh->getMaterial(m); int type = material->getType(); float opacity = material->getOpacity(); float shininess = material->getShininess(); float customValue = material->getCustomValue(); M_BLENDING_MODES blendMode = material->getBlendMode(); MVector3 emit = material->getEmit(); MVector3 diffuse = material->getDiffuse(); MVector3 specular = material->getSpecular(); MVector3 customColor = material->getCustomColor(); MFXRef * FXRef = material->getFXRef(); MFXRef * ZFXRef = material->getZFXRef(); // FX ref state = FXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(FXRef) { MShaderRef * vertShadRef = FXRef->getVertexShaderRef(); MShaderRef * pixShadRef = FXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // Z FX ref state = ZFXRef != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(ZFXRef) { MShaderRef * vertShadRef = ZFXRef->getVertexShaderRef(); MShaderRef * pixShadRef = ZFXRef->getPixelShaderRef(); writeDataRef(file, vertShadRef, rep); writeDataRef(file, pixShadRef, rep); } // data M_fwrite(&type, sizeof(int), 1, file); M_fwrite(&opacity, sizeof(float), 1, file); M_fwrite(&shininess, sizeof(float), 1, file); M_fwrite(&customValue, sizeof(float), 1, file); M_fwrite(&blendMode, sizeof(M_BLENDING_MODES), 1, file); M_fwrite(&emit, sizeof(MVector3), 1, file); M_fwrite(&diffuse, sizeof(MVector3), 1, file); M_fwrite(&specular, sizeof(MVector3), 1, file); M_fwrite(&customColor, sizeof(MVector3), 1, file); // textures pass unsigned int t, texturesPassNumber = material->getTexturesPassNumber(); M_fwrite(&texturesPassNumber, sizeof(int), 1, file); for(t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); unsigned int mapChannel = texturePass->getMapChannel(); M_TEX_COMBINE_MODES combineMode = texturePass->getCombineMode(); // texture id int textureId = getTextureId(mesh, texture); M_fwrite(&textureId, sizeof(int), 1, file); // data M_fwrite(&mapChannel, sizeof(int), 1, file); M_fwrite(&combineMode, sizeof(M_TEX_COMBINE_MODES), 1, file); } } } // Bones { MArmature * armature = mesh->getArmature(); state = armature != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(armature) { unsigned int b, bonesNumber = armature->getBonesNumber(); M_fwrite(&bonesNumber, sizeof(int), 1, file); for(b=0; b<bonesNumber; b++) { MOBone * bone = armature->getBone(b); MObject3d * parent = bone->getParent(); MVector3 position = bone->getPosition(); MVector3 scale = bone->getScale(); MQuaternion rotation = bone->getRotation(); // name writeString(file, bone->getName()); // parent id int parentId = -1; if(parent) { unsigned int id; if(armature->getBoneId(parent->getName(), &id)) parentId = (int)id; } M_fwrite(&parentId, sizeof(int), 1, file); // position / rotation / scale M_fwrite(&position, sizeof(MVector3), 1, file); M_fwrite(&rotation, sizeof(MQuaternion), 1, file); M_fwrite(&scale, sizeof(MVector3), 1, file); } } } // BoundingBox { MBox3d * box = mesh->getBoundingBox(); M_fwrite(box, sizeof(MBox3d), 1, file); } // SubMeshs { unsigned int s, subMeshsNumber = mesh->getSubMeshsNumber(); MSubMesh * subMeshs = mesh->getSubMeshs(); M_fwrite(&subMeshsNumber, sizeof(int), 1, file); for(s=0; s<subMeshsNumber; s++) { MSubMesh * subMesh = &(subMeshs[s]); unsigned int indicesSize = subMesh->getIndicesSize(); unsigned int verticesSize = subMesh->getVerticesSize(); unsigned int normalsSize = subMesh->getNormalsSize(); unsigned int tangentsSize = subMesh->getTangentsSize(); unsigned int texCoordsSize = subMesh->getTexCoordsSize(); unsigned int colorsSize = subMesh->getColorsSize(); M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MColor * colors = subMesh->getColors(); MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MVector3 * tangents = subMesh->getTangents(); MVector2 * texCoords = subMesh->getTexCoords(); MBox3d * box = subMesh->getBoundingBox(); MSkinData * skin = subMesh->getSkinData(); map<unsigned int, unsigned int> * mapChannelOffsets = subMesh->getMapChannelOffsets(); // BoundingBox M_fwrite(box, sizeof(MBox3d), 1, file); // indices M_fwrite(&indicesSize, sizeof(int), 1, file); if(indicesSize > 0) { // indice type M_fwrite(&indicesType, sizeof(M_TYPES), 1, file); switch(indicesType) { case M_USHORT: M_fwrite(indices, sizeof(short), indicesSize, file); break; case M_UINT: M_fwrite(indices, sizeof(int), indicesSize, file); break; } } // vertices M_fwrite(&verticesSize, sizeof(int), 1, file); if(verticesSize > 0) M_fwrite(vertices, sizeof(MVector3), verticesSize, file); // normals M_fwrite(&normalsSize, sizeof(int), 1, file); if(normalsSize > 0) M_fwrite(normals, sizeof(MVector3), normalsSize, file); // tangents M_fwrite(&tangentsSize, sizeof(int), 1, file); if(tangentsSize > 0) M_fwrite(tangents, sizeof(MVector3), tangentsSize, file); // texCoords M_fwrite(&texCoordsSize, sizeof(int), 1, file); if(texCoordsSize > 0) M_fwrite(texCoords, sizeof(MVector2), texCoordsSize, file); // colors M_fwrite(&colorsSize, sizeof(int), 1, file); if(colorsSize > 0) M_fwrite(colors, sizeof(MColor), colorsSize, file); // mapChannels { unsigned int size = mapChannelOffsets->size(); M_fwrite(&size, sizeof(int), 1, file); map<unsigned int, unsigned int>::iterator mit (mapChannelOffsets->begin()), mend(mapChannelOffsets->end()); for(;mit!=mend;++mit) { M_fwrite(&mit->first, sizeof(int), 1, file); M_fwrite(&mit->second, sizeof(int), 1, file); } } // Skins state = skin != NULL; M_fwrite(&state, sizeof(bool), 1, file); if(skin) { // skin point unsigned int p, pointsNumber = skin->getPointsNumber(); M_fwrite(&pointsNumber, sizeof(int), 1, file); for(p=0; p<pointsNumber; p++) { MSkinPoint * skinPoint = skin->getPoint(p); unsigned int vertexId = skinPoint->getVertexId(); unsigned int bonesNumber = skinPoint->getBonesNumber(); unsigned short * bonesIds = skinPoint->getBonesIds(); float * bonesWeights = skinPoint->getBonesWeights(); // data M_fwrite(&vertexId, sizeof(int), 1, file); M_fwrite(&bonesNumber, sizeof(int), 1, file); if(bonesNumber > 0) { M_fwrite(bonesIds, sizeof(short), bonesNumber, file); M_fwrite(bonesWeights, sizeof(float), bonesNumber, file); } } } // Displays unsigned int d, displaysNumber = subMesh->getDisplaysNumber(); M_fwrite(&displaysNumber, sizeof(int), 1, file); for(d=0; d<displaysNumber; d++) { MDisplay * display = subMesh->getDisplay(d); M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); MMaterial * material = display->getMaterial(); M_CULL_MODES cullMode = display->getCullMode(); int materialId = getMaterialId(mesh, material); // data M_fwrite(&primitiveType, sizeof(M_PRIMITIVE_TYPES), 1, file); M_fwrite(&begin, sizeof(int), 1, file); M_fwrite(&size, sizeof(int), 1, file); M_fwrite(&materialId, sizeof(int), 1, file); M_fwrite(&cullMode, sizeof(M_CULL_MODES), 1, file); } } } M_fclose(file); return true; }
void MFixedRenderer::drawScene(MScene * scene, MOCamera * camera) { M_PROFILE_SCOPE(MFixedRenderer::drawScene); struct MEntityLight { MBox3d lightBox; MOLight * light; }; struct MSubMeshPass { unsigned int subMeshId; unsigned int lightsNumber; MObject3d * object; MOLight * lights[4]; }; // sub objects #define MAX_TRANSP_SUBOBJ 4096 static int transpList[MAX_TRANSP_SUBOBJ]; static float transpZList[MAX_TRANSP_SUBOBJ]; static MSubMeshPass transpSubObjs[MAX_TRANSP_SUBOBJ]; // lights list #define MAX_ENTITY_LIGHTS 256 static int entityLightsList[MAX_ENTITY_LIGHTS]; static float entityLightsZList[MAX_ENTITY_LIGHTS]; static MEntityLight entityLights[MAX_ENTITY_LIGHTS]; // get render MRenderingContext * render = MEngine::getInstance()->getRenderingContext(); render->enableLighting(); render->enableBlending(); // make frustum MFrustum * frustum = camera->getFrustum(); frustum->makeVolume(camera); // update visibility updateVisibility(scene, camera); // fog enableFog(camera); // camera MVector3 cameraPos = camera->getTransformedPosition(); // transp sub obj number unsigned int transpSubObsNumber = 0; // lights unsigned int l; unsigned int lSize = scene->getLightsNumber(); // entities unsigned int i; unsigned int eSize = scene->getEntitiesNumber(); for(i=0; i<eSize; i++) { // get entity MOEntity * entity = scene->getEntityByIndex(i); MMesh * mesh = entity->getMesh(); if(! entity->isActive()) continue; if(! entity->isVisible()) { if(mesh) { MArmature * armature = mesh->getArmature(); MArmatureAnim * armatureAnim = mesh->getArmatureAnim(); if(armature) { // animate armature if(armatureAnim) animateArmature( mesh->getArmature(), mesh->getArmatureAnim(), entity->getCurrentFrame() ); // TODO : optimize and add a tag to desactivate it updateSkinning(mesh, armature); (*entity->getBoundingBox()) = (*mesh->getBoundingBox()); } } continue; } // draw mesh if(mesh) { MVector3 scale = entity->getTransformedScale(); MBox3d * entityBox = entity->getBoundingBox(); float minScale = scale.x; minScale = MIN(minScale, scale.y); minScale = MIN(minScale, scale.z); minScale = 1.0f / minScale; unsigned int entityLightsNumber = 0; for(l=0; l<lSize; l++) { // get entity MOLight * light = scene->getLightByIndex(l); if(! light->isActive()) continue; if(! light->isVisible()) continue; // light box MVector3 lightPos = light->getTransformedPosition(); MVector3 localPos = entity->getInversePosition(lightPos); float localRadius = light->getRadius() * minScale; MBox3d lightBox( MVector3(localPos - localRadius), MVector3(localPos + localRadius) ); if(! entityBox->isInCollisionWith(&lightBox)) continue; MEntityLight * entityLight = &entityLights[entityLightsNumber]; entityLight->lightBox = lightBox; entityLight->light = light; entityLightsNumber++; if(entityLightsNumber == MAX_ENTITY_LIGHTS) break; } // animate armature if(mesh->getArmature() && mesh->getArmatureAnim()) animateArmature( mesh->getArmature(), mesh->getArmatureAnim(), entity->getCurrentFrame() ); // animate textures if(mesh->getTexturesAnim()) animateTextures(mesh, mesh->getTexturesAnim(), entity->getCurrentFrame()); // animate materials if(mesh->getMaterialsAnim()) animateMaterials(mesh, mesh->getMaterialsAnim(), entity->getCurrentFrame()); unsigned int s; unsigned int sSize = mesh->getSubMeshsNumber(); for(s=0; s<sSize; s++) { MSubMesh * subMesh = &mesh->getSubMeshs()[s]; MBox3d * box = subMesh->getBoundingBox(); // check if submesh visible if(sSize > 1) { MVector3 * min = box->getMin(); MVector3 * max = box->getMax(); MVector3 points[8] = { entity->getTransformedVector(MVector3(min->x, min->y, min->z)), entity->getTransformedVector(MVector3(min->x, max->y, min->z)), entity->getTransformedVector(MVector3(max->x, max->y, min->z)), entity->getTransformedVector(MVector3(max->x, min->y, min->z)), entity->getTransformedVector(MVector3(min->x, min->y, max->z)), entity->getTransformedVector(MVector3(min->x, max->y, max->z)), entity->getTransformedVector(MVector3(max->x, max->y, max->z)), entity->getTransformedVector(MVector3(max->x, min->y, max->z)) }; if(! frustum->isVolumePointsVisible(points, 8)) continue; } // subMesh center MVector3 center = (*box->getMin()) + ((*box->getMax()) - (*box->getMin()))*0.5f; center = entity->getTransformedVector(center); // sort entity lights unsigned int lightsNumber = 0; for(l=0; l<entityLightsNumber; l++) { MEntityLight * entityLight = &entityLights[l]; if(! box->isInCollisionWith(&entityLight->lightBox)) continue; MOLight * light = entityLight->light; float z = (center - light->getTransformedPosition()).getLength(); entityLightsList[lightsNumber] = l; entityLightsZList[l] = (1.0f/z)*light->getRadius(); lightsNumber++; } if(lightsNumber > 1) sortFloatList(entityLightsList, entityLightsZList, 0, (int)lightsNumber-1); // local lights if(lightsNumber > 4) lightsNumber = 4; for(l=0; l<lightsNumber; l++) { MEntityLight * entityLight = &entityLights[entityLightsList[l]]; MOLight * light = entityLight->light; // attenuation float quadraticAttenuation = (8.0f / light->getRadius()); quadraticAttenuation = (quadraticAttenuation*quadraticAttenuation)*light->getIntensity(); // color MVector3 color = light->getFinalColor(); // set light render->enableLight(l); render->setLightPosition(l, light->getTransformedPosition()); render->setLightDiffuse(l, MVector4(color)); render->setLightSpecular(l, MVector4(color)); render->setLightAmbient(l, MVector3(0, 0, 0)); render->setLightAttenuation(l, 1, 0, quadraticAttenuation); // spot render->setLightSpotAngle(l, light->getSpotAngle()); if(light->getSpotAngle() < 90){ render->setLightSpotDirection(l, light->getRotatedVector(MVector3(0, 0, -1)).getNormalized()); render->setLightSpotExponent(l, light->getSpotExponent()); } else { render->setLightSpotExponent(l, 0.0f); } } for(l=lightsNumber; l<4; l++){ render->disableLight(l); } render->pushMatrix(); render->multMatrix(entity->getMatrix()); // draw opaques drawOpaques(subMesh, mesh->getArmature()); if(subMesh->hasTransparency()) { if(transpSubObsNumber < MAX_TRANSP_SUBOBJ) { // transparent subMesh pass MSubMeshPass * subMeshPass = &transpSubObjs[transpSubObsNumber]; // lights subMeshPass->lightsNumber = lightsNumber; for(l=0; l<lightsNumber; l++) subMeshPass->lights[l] = entityLights[entityLightsList[l]].light; // z distance to camera float z = getDistanceToCam(camera, center); // set values transpList[transpSubObsNumber] = transpSubObsNumber; transpZList[transpSubObsNumber] = z; subMeshPass->subMeshId = s; subMeshPass->object = entity; transpSubObsNumber++; } } render->popMatrix(); } mesh->updateBoundingBox(); (*entity->getBoundingBox()) = (*mesh->getBoundingBox()); } } // texts unsigned int tSize = scene->getTextsNumber(); for(i=0; i<tSize; i++) { MOText * text = scene->getTextByIndex(i); if(text->isActive() && text->isVisible()) { // transparent pass MSubMeshPass * subMeshPass = &transpSubObjs[transpSubObsNumber]; // center MBox3d * box = text->getBoundingBox(); MVector3 center = (*box->getMin()) + ((*box->getMax()) - (*box->getMin()))*0.5f; center = text->getTransformedVector(center); // z distance to camera float z = getDistanceToCam(camera, center); // set values transpList[transpSubObsNumber] = transpSubObsNumber; transpZList[transpSubObsNumber] = z; subMeshPass->object = text; transpSubObsNumber++; } } // sort transparent list if(transpSubObsNumber > 1) sortFloatList(transpList, transpZList, 0, (int)transpSubObsNumber-1); // draw transparents for(i=0; i<transpSubObsNumber; i++) { MSubMeshPass * subMeshPass = &transpSubObjs[transpList[i]]; MObject3d * object = subMeshPass->object; // objects switch(object->getType()) { case M_OBJECT3D_ENTITY: { MOEntity * entity = (MOEntity *)object; unsigned int subMeshId = subMeshPass->subMeshId; MMesh * mesh = entity->getMesh(); MSubMesh * subMesh = &mesh->getSubMeshs()[subMeshId]; // animate armature if(mesh->getArmature() && mesh->getArmatureAnim()) animateArmature( mesh->getArmature(), mesh->getArmatureAnim(), entity->getCurrentFrame() ); // animate textures if(mesh->getTexturesAnim()) animateTextures(mesh, mesh->getTexturesAnim(), entity->getCurrentFrame()); // animate materials if(mesh->getMaterialsAnim()) animateMaterials(mesh, mesh->getMaterialsAnim(), entity->getCurrentFrame()); // lights for(l=0; l<subMeshPass->lightsNumber; l++) { MOLight * light = subMeshPass->lights[l]; // attenuation float quadraticAttenuation = (8.0f / light->getRadius()); quadraticAttenuation = (quadraticAttenuation*quadraticAttenuation)*light->getIntensity(); // color MVector3 color = light->getFinalColor(); // set light render->enableLight(l); render->setLightPosition(l, light->getTransformedPosition()); render->setLightDiffuse(l, MVector4(color)); render->setLightSpecular(l, MVector4(color)); render->setLightAmbient(l, MVector3(0, 0, 0)); render->setLightAttenuation(l, 1, 0, quadraticAttenuation); // spot render->setLightSpotAngle(l, light->getSpotAngle()); if(light->getSpotAngle() < 90){ render->setLightSpotDirection(l, light->getRotatedVector(MVector3(0, 0, -1)).getNormalized()); render->setLightSpotExponent(l, light->getSpotExponent()); } else { render->setLightSpotExponent(l, 0.0f); } } for(l=subMeshPass->lightsNumber; l<4; l++){ render->disableLight(l); } render->pushMatrix(); render->multMatrix(entity->getMatrix()); drawTransparents(subMesh, mesh->getArmature()); render->popMatrix(); mesh->updateBoundingBox(); (*entity->getBoundingBox()) = (*mesh->getBoundingBox()); } break; case M_OBJECT3D_TEXT: { MOText * text = (MOText *)object; render->pushMatrix(); render->multMatrix(text->getMatrix()); drawText(text); render->popMatrix(); } break; } } render->disableLighting(); render->disableFog(); }
void MBLookAt::update(void) { MEngine * engine = MEngine::getInstance(); MLevel * level = engine->getLevel(); MScene * scene = level->getCurrentScene(); MObject3d * parent = getParentObject(); const char * targetName = m_targetName.getData(); if(strcmp(targetName, "none") == 0) return; // target object MObject3d * object = scene->getObjectByName(targetName); if(! object) return; // direction MVector3 direction = object->getTransformedPosition() - parent->getTransformedPosition(); if(direction.x == 0 && direction.y == 0 && direction.z == 0) return; float angle; float roll; MVector3 axis; // compute initial roll MVector3 ZAxis = parent->getInverseRotatedVector(MVector3(0, 0, 1)).getNormalized(); ZAxis.z = 0; ZAxis.normalize(); if(ZAxis.x == 0 && ZAxis.y == 0) { MVector3 YAxis = parent->getInverseRotatedVector(MVector3(0, 1, 0)).getNormalized(); YAxis.z = 0; YAxis.normalize(); axis = MVector3(0, 1, 0).crossProduct(YAxis); roll = acosf(MVector3(0, 1, 0).dotProduct(YAxis)); if(MVector3(0, 0, 1).dotProduct(axis) < 0) roll = -roll; } else { axis = MVector3(0, 1, 0).crossProduct(ZAxis); roll = acosf(MVector3(0, 1, 0).dotProduct(ZAxis)); if(MVector3(0, 0, 1).dotProduct(axis) < 0) roll = -roll; } if(roll < 0.001f && roll > -0.001f) roll = 0; // look-at MVector3 cameraAxis = MVector3(0, 0, -1); axis = cameraAxis.crossProduct(direction); angle = acosf(cameraAxis.dotProduct(direction.getNormalized())); parent->setAxisAngleRotation(axis, (float)(angle * RAD_TO_DEG)); parent->updateMatrix(); // set roll ZAxis = parent->getInverseRotatedVector(MVector3(0, 0, 1)).getNormalized();; ZAxis.z = 0; ZAxis.normalize(); if(ZAxis.x == 0 && ZAxis.y == 0) { parent->addAxisAngleRotation(MVector3(0, 0, 1), (float)(-roll*RAD_TO_DEG)); } else { axis = MVector3(0, 1, 0).crossProduct(ZAxis); angle = acosf(MVector3(0, 1, 0).dotProduct(ZAxis)); if(angle < 0.001f && angle > -0.001f) angle = 0; if(MVector3(0, 0, 1).dotProduct(axis) < 0) angle = -angle; parent->addAxisAngleRotation(MVector3(0, 0, 1), (float)((angle-roll)*RAD_TO_DEG)); } }
void MScene::deleteObject(MObject3d * object) { if(! object) return; unsigned int i; unsigned int oSize; // objects switch(object->getType()) { case M_OBJECT3D_ENTITY: { // entities oSize = m_entities.size(); for(i=0; i<oSize; i++){ MObject3d * obj = m_entities[i]; if(obj == object){ m_entities.erase(m_entities.begin() + i); break; } } } break; case M_OBJECT3D_CAMERA: { // cameras oSize = m_cameras.size(); for(i=0; i<oSize; i++){ MObject3d * obj = m_cameras[i]; if(obj == object){ m_cameras.erase(m_cameras.begin() + i); break; } } } break; case M_OBJECT3D_LIGHT: { // lights oSize = m_lights.size(); for(i=0; i<oSize; i++){ MObject3d * obj = m_lights[i]; if(obj == object){ m_lights.erase(m_lights.begin() + i); break; } } } break; case M_OBJECT3D_SOUND: { // sounds oSize = m_sounds.size(); for(i=0; i<oSize; i++){ MObject3d * obj = m_sounds[i]; if(obj == object){ m_sounds.erase(m_sounds.begin() + i); break; } } } break; case M_OBJECT3D_TEXT: { // sounds oSize = m_texts.size(); for(i=0; i<oSize; i++){ MObject3d * obj = m_texts[i]; if(obj == object){ m_texts.erase(m_texts.begin() + i); break; } } } break; } // objects pointer oSize = m_objects.size(); for(i=0; i<oSize; i++){ MObject3d * obj = m_objects[i]; if(obj == object) { obj->unLink(); obj->unlinkChilds(); m_objects.erase(m_objects.begin() + i); SAFE_DELETE(obj); return; } } }
void MScene::prepareCollisionObject(MOEntity * entity) { MPhysicsContext * physics = MEngine::getInstance()->getPhysicsContext(); MPhysicsProperties * phyProps = entity->getPhysicsProperties(); if(! phyProps) return; unsigned int shapeId = phyProps->getShapeId(); if(shapeId == 0) return; // has physics parent MPhysicsProperties * parentPhyProps = NULL; MOEntity * parentEntity = NULL; if(! phyProps->isGhost()) { MObject3d * parentObject = entity->getParent(); if(parentObject) { if(parentObject->getType() == M_OBJECT3D_ENTITY) { parentEntity = (MOEntity*)parentObject; parentPhyProps = parentEntity->getPhysicsProperties(); } } } if(parentPhyProps) // add shape to parent multi-shape { MVector3 position = entity->getPosition() * parentEntity->getTransformedScale(); MQuaternion rotation = entity->getRotation(); phyProps->setShapeId(shapeId); physics->addChildShape(parentPhyProps->getShapeId(), shapeId, position, rotation); } else // create collision object { unsigned int collisionObjectId; if(phyProps->isGhost()) { MVector3 euler = entity->getTransformedRotation(); physics->createGhost( &collisionObjectId, shapeId, entity->getTransformedPosition(), MQuaternion(euler.x, euler.y, euler.z) ); phyProps->setShapeId(shapeId); phyProps->setCollisionObjectId(collisionObjectId); } else { physics->createRigidBody( &collisionObjectId, shapeId, entity->getPosition(), entity->getRotation(), phyProps->getMass() ); phyProps->setShapeId(shapeId); phyProps->setCollisionObjectId(collisionObjectId); physics->setObjectRestitution(collisionObjectId, phyProps->getRestitution()); physics->setObjectDamping(collisionObjectId, phyProps->getLinearDamping(), phyProps->getAngularDamping()); physics->setObjectAngularFactor(collisionObjectId, phyProps->getAngularFactor()); physics->setObjectLinearFactor(collisionObjectId, *phyProps->getLinearFactor()); physics->setObjectFriction(collisionObjectId, phyProps->getFriction()); } // deactivate if(! entity->isActive()) physics->deactivateObject(collisionObjectId); // set user pointer (entity) physics->setObjectUserPointer(collisionObjectId, entity); } }