void MScene::preparePhysics(void) { MPhysicsContext * physics = MEngine::getInstance()->getPhysicsContext(); if(! physics) return; physics->init(MVector3(-10000), MVector3(10000)); physics->setWorldGravity(m_gravity); // create shapes unsigned int i; unsigned int size = getEntitiesNumber(); for(i=0; i<size; i++) { MOEntity * entity = getEntityByIndex(i); prepareCollisionShape(entity); } // create objects for(i=0; i<size; i++) { MOEntity * entity = getEntityByIndex(i); prepareCollisionObject(entity); } // create constraints for(i=0; i<size; i++) { MOEntity * entity = getEntityByIndex(i); prepareConstraints(entity); } }
MVector3 MObject3d::getTransformedScale(void) const { float xSize = m_matrix.getRotatedVector3(MVector3(1, 0, 0)).getLength(); float ySize = m_matrix.getRotatedVector3(MVector3(0, 1, 0)).getLength(); float zSize = m_matrix.getRotatedVector3(MVector3(0, 0, 1)).getLength(); return MVector3(xSize, ySize, zSize); }
void MOCamera::updateListener(void) { MSoundContext * soundContext = MEngine::getInstance()->getSoundContext(); MVector3 position = getTransformedPosition(); MVector3 direction = getRotatedVector(MVector3(0, 0, -1)); MVector3 up = getRotatedVector(MVector3(0, 1, 0)); soundContext->updateListenerPosition(position, direction, up); }
void MOEntity::updateVisibility(MOCamera * camera) { if(m_isInvisible){ setVisible(false); return; } MFrustum * frustum = camera->getFrustum(); MVector3 * min = m_boundingBox.getMin(); MVector3 * max = m_boundingBox.getMax(); MVector3 points[8] = { getTransformedVector(MVector3(min->x, min->y, min->z)), getTransformedVector(MVector3(min->x, max->y, min->z)), getTransformedVector(MVector3(max->x, max->y, min->z)), getTransformedVector(MVector3(max->x, min->y, min->z)), getTransformedVector(MVector3(min->x, min->y, max->z)), getTransformedVector(MVector3(min->x, max->y, max->z)), getTransformedVector(MVector3(max->x, max->y, max->z)), getTransformedVector(MVector3(max->x, min->y, max->z)) }; // is box in frustum setVisible(frustum->isVolumePointsVisible(points, 8)); }
MVector3 MQuaternion::getAxis(void) const { float v = values[3]; if(1.0f < v){ v = 1.0f; } else if(-1.0f > v){ v = -1.0f; } float angle = (2.0f * acosf(v)); float scale = (float)sin(angle / 2); MVector3 result; if(scale != 0) { scale = 1.0f / scale; result.x = scale * values[0]; result.y = scale * values[1]; result.z = scale * values[2]; return result; } return MVector3(0.0f, 1.0f, 0.0f); }
float MFixedRenderer::getDistanceToCam(MOCamera * camera, const MVector3 & pos) { if(! camera->isOrtho()) { return (pos - camera->getTransformedPosition()).getSquaredLength(); } MVector3 axis = camera->getRotatedVector(MVector3(0, 0, -1)).getNormalized(); float dist = (pos - camera->getTransformedPosition()).dotProduct(axis); return dist*dist; }
MVector3 MOCamera::getProjectedPoint(const MVector3 & point) const { MVector4 v = m_currentViewMatrix * MVector4(point); v = m_currentProjMatrix * v; v.x = v.x / v.w; v.y = v.y / v.w; v.z = v.z / v.w; v.x = m_currentViewport[0] + (m_currentViewport[2] * ((v.x + 1) / 2.0f)); v.y = m_currentViewport[1] + (m_currentViewport[3] * ((v.y + 1) / 2.0f)); v.z = (v.z + 1) / 2.0f; return MVector3(v.x, v.y, v.z); }
MVector3 MOCamera::getUnProjectedPoint(const MVector3 & point) const { MVector4 nPoint; nPoint.x = (2 * ((point.x - m_currentViewport[0]) / ((float)m_currentViewport[2]))) - 1; nPoint.y = (2 * ((point.y - m_currentViewport[1]) / ((float)m_currentViewport[3]))) - 1; nPoint.z = (2 * point.z) - 1; nPoint.w = 1; MMatrix4x4 matrix = (m_currentProjMatrix * m_currentViewMatrix).getInverse(); MVector4 v = matrix * nPoint; if(v.w == 0) return getTransformedPosition(); float iw = 1.0f / v.w; return MVector3(v.x, v.y, v.z)*iw; }
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 MOLight::updateVisibility(MOCamera * camera) { MFrustum * frustum = camera->getFrustum(); // TODO: use different test for spot and directional MVector3 min = getTransformedPosition() - m_radius; MVector3 max = getTransformedPosition() + m_radius; MVector3 points[8] = { MVector3(min.x, min.y, min.z), MVector3(min.x, max.y, min.z), MVector3(max.x, max.y, min.z), MVector3(max.x, min.y, min.z), MVector3(min.x, min.y, max.z), MVector3(min.x, max.y, max.z), MVector3(max.x, max.y, max.z), MVector3(max.x, min.y, max.z) }; // is box in frustum setVisible(frustum->isVolumePointsVisible(points, 8)); }
MVector3 computeTangent( const MVector3 & P1, const MVector3 & P2, const MVector3 & P3, const MVector2 & UV1, const MVector2 & UV2, const MVector2 & UV3) { MVector3 Edge1 = P2 - P1; MVector3 Edge2 = P3 - P1; MVector2 Edge1uv = UV2 - UV1; MVector2 Edge2uv = UV3 - UV1; float cp = Edge1uv.y * Edge2uv.x - Edge1uv.x * Edge2uv.y; if(cp != 0.0f) { float mul = 1.0f / cp; MVector3 tangent = (Edge1 * -Edge2uv.y + Edge2 * Edge1uv.y) * mul; return tangent.getNormalized(); } return MVector3(0.0f, 0.0f, 0.0f); }
int ScriptAddQuad() { MEngine* engine = MEngine::getInstance(); MScriptContext* script = engine->getScriptContext(); if(g_Cnt >= MAX_QUAD) return 0; MVector3 verts[4]; MVector2 uvs[4]; for(int i = 0; i < 4; ++i) { MVector2 vert; script->getFloatArray(i*2, &vert.x, 2); verts[i] = MVector3(vert.x, vert.y, 1); script->getFloatArray(i*2 + 1, &uvs[i].x, 2); } // copy the vertices g_Vertices[g_Cnt*6 + 0] = verts[0]; g_Vertices[g_Cnt*6 + 1] = verts[1]; g_Vertices[g_Cnt*6 + 2] = verts[2]; g_Vertices[g_Cnt*6 + 3] = verts[0]; g_Vertices[g_Cnt*6 + 4] = verts[2]; g_Vertices[g_Cnt*6 + 5] = verts[3]; // copy the UVs in order g_UVs[g_Cnt*6 + 0] = uvs[0]; g_UVs[g_Cnt*6 + 1] = uvs[1]; g_UVs[g_Cnt*6 + 2] = uvs[2]; g_UVs[g_Cnt*6 + 3] = uvs[0]; g_UVs[g_Cnt*6 + 4] = uvs[2]; g_UVs[g_Cnt*6 + 5] = uvs[3]; for(int i = 0; i < 6; ++i) g_Colours[g_Cnt*6 + i] = g_CurrentColour; g_Cnt ++; return 0; }
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 MFixedRenderer::drawDisplay(MSubMesh * subMesh, MDisplay * display, MVector3 * vertices, MVector3 * normals, MColor * colors) { M_PROFILE_SCOPE(MFixedRenderer::drawDisplay); MEngine * engine = MEngine::getInstance(); MRenderingContext * render = engine->getRenderingContext(); render->setColor4(MVector4(1, 1, 1, 1)); // get material MMaterial * material = display->getMaterial(); { float opacity = material->getOpacity(); if(opacity <= 0.0f) return; // data M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MVector2 * texCoords = subMesh->getTexCoords(); // begin / size unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); // get properties M_PRIMITIVE_TYPES primitiveType = display->getPrimitiveType(); M_BLENDING_MODES blendMode = material->getBlendMode(); M_CULL_MODES cullMode = display->getCullMode(); MVector3 * diffuse = material->getDiffuse(); MVector3 * specular = material->getSpecular(); MVector3 * emit = material->getEmit(); float shininess = material->getShininess(); // get current fog color MVector3 currentFogColor; render->getFogColor(¤tFogColor); // set cull mode if(cullMode == M_CULL_NONE){ render->disableCullFace(); } else{ render->enableCullFace(); render->setCullMode(cullMode); } // texture passes unsigned int texturesPassNumber = MIN(8, material->getTexturesPassNumber()); // set blending mode render->setBlendingMode(blendMode); // alpha test if(blendMode != M_BLENDING_ALPHA && texturesPassNumber > 0) { MTexturePass * texturePass = material->getTexturePass(0); MTexture * texture = texturePass->getTexture(); if(texture) { if(texture->getTextureRef()->getComponents() > 3) render->setAlphaTest(0.5f); } } // set fog color depending on blending switch(blendMode) { case M_BLENDING_ADD: case M_BLENDING_LIGHT: render->setFogColor(MVector3(0, 0, 0)); break; case M_BLENDING_PRODUCT: render->setFogColor(MVector3(1, 1, 1)); break; } // fixed pipeline { // no FX render->bindFX(0); // Vertex render->enableVertexArray(); render->setVertexPointer(M_FLOAT, 3, vertices); // Normal if(normals) { render->enableNormalArray(); render->setNormalPointer(M_FLOAT, normals); } // Color if(colors) { render->disableLighting(); render->enableColorArray(); render->setColorPointer(M_UBYTE, 4, colors); } // Material render->setMaterialDiffuse(MVector4(diffuse->x, diffuse->y, diffuse->z, opacity)); render->setMaterialSpecular(MVector4(*specular)); render->setMaterialAmbient(MVector4()); render->setMaterialEmit(MVector4(*emit)); render->setMaterialShininess(shininess); // switch to texture matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_TEXTURE); else render->disableTexture(); // Textures int id = texturesPassNumber; for(unsigned int t=0; t<texturesPassNumber; t++) { MTexturePass * texturePass = material->getTexturePass(t); MTexture * texture = texturePass->getTexture(); if((! texture) || (! texCoords)) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); continue; } // texCoords unsigned int offset = 0; if(subMesh->isMapChannelExist(texturePass->getMapChannel())) offset = subMesh->getMapChannelOffset(texturePass->getMapChannel()); // texture id unsigned int textureId = 0; MTextureRef * texRef = texture->getTextureRef(); if(texRef) textureId = texRef->getTextureId(); // bind texture render->bindTexture(textureId, t); render->enableTexture(); render->setTextureCombineMode(texturePass->getCombineMode()); render->setTextureUWrapMode(texture->getUWrapMode()); render->setTextureVWrapMode(texture->getVWrapMode()); // texture matrix render->loadIdentity(); render->translate(MVector2(0.5f, 0.5f)); render->scale(*texture->getTexScale()); render->rotate(MVector3(0, 0, -1), texture->getTexRotate()); render->translate(MVector2(-0.5f, -0.5f)); render->translate(*texture->getTexTranslate()); // texture coords render->enableTexCoordArray(); render->setTexCoordPointer(M_FLOAT, 2, texCoords + offset); } // switch back to modelview matrix mode if(texturesPassNumber > 0) render->setMatrixMode(M_MATRIX_MODELVIEW); // draw if(indices) { switch(indicesType) { case M_USHORT: render->drawElement(primitiveType, size, indicesType, (unsigned short*)indices + begin); break; case M_UINT: render->drawElement(primitiveType, size, indicesType, (unsigned int*)indices + begin); break; } } else{ render->drawArray(primitiveType, begin, size); } // disable arrays render->disableVertexArray(); if(normals) render->disableNormalArray(); if(colors) render->disableColorArray(); // restore textures for(int t=(int)(id-1); t>=0; t--) { render->bindTexture(0, t); render->disableTexture(); render->disableTexCoordArray(); render->setTextureCombineMode(M_TEX_COMBINE_MODULATE); render->setMatrixMode(M_MATRIX_TEXTURE); render->loadIdentity(); render->setMatrixMode(M_MATRIX_MODELVIEW); } } // restore fog and alpha test render->setFogColor(currentFogColor); if(blendMode != M_BLENDING_ALPHA) render->setAlphaTest(0.0f); // restore lighting if(colors) render->enableLighting(); } }
void MGui2d::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; if(isPressed()) // pressed { render->setColor4(getPressedColor()); if(hasPressedTexture()) { render->enableTexture(); drawTexturedQuad(getPressedTexture()); } else { render->disableTexture(); drawQuad(); } } else if(isHighLight()) // highLight { render->setColor4(getHighLightColor()); if(hasHighLightTexture()){ render->enableTexture(); drawTexturedQuad(getHighLightTexture()); } else { render->disableTexture(); drawQuad(); } } else // normal { render->setColor4(getNormalColor()); if(hasNormalTexture()) { render->enableTexture(); drawTexturedQuad(getNormalTexture()); } else { render->disableTexture(); drawQuad(); } } if(isDrawingText() && (getText() != NULL)) { render->enableTexture(); render->setColor4(getTextColor()); getFont()->draw(getText(), getPosition(), getTextSize()); } // draw shadows if(hasShadow()) { render->pushMatrix(); render->translate(MVector3(getPosition().x, getPosition().y, 0)); drawShadow(); render->popMatrix(); } }
bool createShape(MOEntity * entity, MPhysicsProperties * phyProps, unsigned int * shapeId) { MPhysicsContext * physics = MEngine::getInstance()->getPhysicsContext(); // get bounding box MBox3d * box = entity->getBoundingBox(); MVector3 scale = entity->getTransformedScale(); // swith shapes switch(phyProps->getCollisionShape()) { default: case M_COLLISION_SHAPE_BOX: physics->createBoxShape(shapeId, (box->max - box->min)*scale*0.5f); break; case M_COLLISION_SHAPE_SPHERE: { MVector3 vec = (box->max - box->min)*scale*0.5f; float radius = vec.x; radius = MAX(radius, vec.y); radius = MAX(radius, vec.z); physics->createSphereShape(shapeId, radius); } break; case M_COLLISION_SHAPE_CONE: { MVector3 vec = (box->max - box->min)*scale; float height = vec.y; float radius = vec.x*0.5f; radius = MAX(radius, vec.z*0.5f); physics->createConeShape(shapeId, radius, height); } break; case M_COLLISION_SHAPE_CAPSULE: { MVector3 vec = (box->max - box->min)*scale; float height = vec.y; float radius = vec.x*0.5f; radius = MAX(radius, vec.z*0.5f); physics->createCylinderShape(shapeId, radius, height); } break; case M_COLLISION_SHAPE_CYLINDER: { MVector3 vec = (box->max - box->min)*scale; float height = vec.y; float radius = vec.x*0.5f; radius = MAX(radius, vec.z*0.5f); physics->createCylinderShape(shapeId, radius, height); } break; case M_COLLISION_SHAPE_CONVEX_HULL: { MMesh * mesh = entity->getMesh(); if(mesh) { MSubMesh * subMeshs = mesh->getSubMeshs(); unsigned int subMeshsNumber = mesh->getSubMeshsNumber(); if(subMeshsNumber == 0) return false; if(subMeshsNumber == 1) { MSubMesh * subMesh = &subMeshs[0]; if(subMesh->getVerticesSize() > 0) physics->createConvexHullShape(shapeId, subMesh->getVertices(), subMesh->getVerticesSize(), entity->getScale()); } else { physics->createMultiShape(shapeId); unsigned int s; for(s=0; s<subMeshsNumber; s++) { unsigned int subShapeId; MSubMesh * subMesh = &subMeshs[s]; if(subMesh->getVerticesSize() > 0) { physics->createConvexHullShape(&subShapeId, subMesh->getVertices(), subMesh->getVerticesSize(), entity->getScale()); physics->addChildShape(*shapeId, subShapeId, MVector3(), MQuaternion()); } } } } else{ return false; } } break; case M_COLLISION_SHAPE_TRIANGLE_MESH: { MMesh * mesh = entity->getMesh(); if(mesh) { MSubMesh * subMeshs = mesh->getSubMeshs(); unsigned int subMeshsNumber = mesh->getSubMeshsNumber(); if(subMeshsNumber == 0) return false; if(subMeshsNumber == 1) { MSubMesh * subMesh = &subMeshs[0]; if(subMesh->getVerticesSize() >= 3) physics->createTriangleMeshShape(shapeId, subMesh->getVertices(), subMesh->getVerticesSize(), subMesh->getIndices(), subMesh->getIndicesSize(), subMesh->getIndicesType(), entity->getScale() ); } else { physics->createMultiShape(shapeId); unsigned int s; for(s=0; s<subMeshsNumber; s++) { unsigned int subShapeId; MSubMesh * subMesh = &subMeshs[s]; if(subMesh->getVerticesSize() >= 3) { physics->createTriangleMeshShape(&subShapeId, subMesh->getVertices(), subMesh->getVerticesSize(), subMesh->getIndices(), subMesh->getIndicesSize(), subMesh->getIndicesType(), entity->getScale() ); physics->addChildShape(*shapeId, subShapeId, MVector3(), MQuaternion()); } } } } else{ return false; } } break; } return true; }
void MOText::prepare(void) { MFont * font = getFont(); const char * text = m_text.getData(); if(! (strlen(text) > 0 && font)){ m_boundingBox = MBox3d(); return; } MVector3 * min = m_boundingBox.getMin(); MVector3 * max = m_boundingBox.getMax(); (*min) = (*max) = MVector3(0, 0, 0); float tabSize = m_size*2; float fontSize = (float)font->getFontSize(); float widthFactor = font->getTextureWith() / fontSize; float heightFactor = font->getTextureHeight() / fontSize; float xc = 0, yc = 0; unsigned int i; unsigned int size = strlen(text); for(i=0; i<size; i++) { if(text[i] == '\n') // return { yc += m_size; xc = 0; continue; } if(text[i] == '\t') // tab { int tab = (int)(xc / tabSize) + 1; xc = tab*tabSize; continue; } // get character unsigned int charCode = (unsigned int)((unsigned char)text[i]); MCharacter * character = font->getCharacter(charCode); if(! character) continue; MVector2 scale = character->getScale(); MVector2 offset = character->getOffset() * m_size; float width = scale.x * widthFactor * m_size; float height = scale.y * heightFactor * m_size; MVector2 charMin = MVector2(xc, yc) + offset; MVector2 charMax = charMin + MVector2(width, height); if(charMin.x < min->x) min->x = charMin.x; if(charMin.y < min->y) min->y = charMin.y; if(charMax.x > max->x) max->x = charMax.x; if(charMax.y > max->y) max->y = charMax.y; //move to next character xc += character->getXAdvance() * m_size; } updateLinesOffset(); }
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 MGuiFileBrowser::updateMainWin(void) { m_mainWin->clear(); m_files.clear(); m_files.push_back(string("..")); if(readDirectory(m_currentDirectory.getSafeString(), &m_files)) { char filename[256]; // prepare unsigned int f, fSize = m_files.size(); for(f=0; f<fSize; f++) { const char * name = m_files[f].c_str(); if(f > 0) { getGlobalFilename(filename, m_currentDirectory.getSafeString(), name); if(isDirectory(filename)) m_files[f] = "/" + m_files[f]; } } // sort sort(m_files.begin(), m_files.end(), stringCompare); // scan for(f=0; f<fSize; f++) { float y = m_browserHeight*f; const char * name = m_files[f].c_str(); string textName = name; float grey = 0.24f; if((f%2) == 0) grey = 0.2f; MGuiButton * button = new MGuiButton( MVector2(0, y), MVector2(m_mainWin->getScale().x, m_browserHeight), MVector3(grey*0.9f, grey*1.1f, grey*1.3f), NULL ); button->setHighLightColor(MVector3(0.35f)); button->setPressedColor(MVector3(0.35f)); m_mainWin->addButton(button); MGuiText * text = new MGuiText(textName.c_str(), MVector2(0, y), 16, m_browserTextColor); m_mainWin->addText(text); } } m_mainWin->resizeScroll(); }
void MGuiWindow::draw(void) { MRenderingContext * render = MGui::getInstance()->getRenderingContext(); if(! isVisible()) return; MWindow * window = MWindow::getInstance(); rescaleScrollingBar(); render->enableScissorTest(); render->setScissor((int)getPosition().x, window->getHeight() - (int)getPosition().y - (unsigned int)getScale().y, (unsigned int)getScale().x, (unsigned int)getScale().y); // normal clear if((getNormalColor().w >= 1.0f) && (! hasNormalTexture())) { render->setClearColor(getNormalColor()); render->clear(M_BUFFER_COLOR); MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_DRAW; if(m_pointerEvent) m_pointerEvent(this, &guiEvent); // 2d mode set2dMode(render); render->disableDepthTest(); render->disableCullFace(); render->disableLighting(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); render->enableTexture(); } else { // background set2dMode(render); render->disableDepthTest(); render->disableCullFace(); render->disableLighting(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); if(hasNormalTexture()) // texture clear { render->enableTexture(); render->setColor4(getNormalColor()); drawTexturedQuad(getNormalTexture()); } else if(getNormalColor().w < 1.0f) { render->disableTexture(); render->setColor4(getNormalColor()); drawQuad(); } if(m_pointerEvent) { MGuiEvent guiEvent; guiEvent.type = MGUI_EVENT_DRAW; m_pointerEvent(this, &guiEvent); // 2d mode set2dMode(render); render->disableDepthTest(); render->disableCullFace(); render->disableLighting(); render->enableBlending(); render->setBlendingMode(M_BLENDING_ALPHA); render->enableTexture(); } } // gui render->pushMatrix(); render->translate(MVector3(getPosition().x, getPosition().y, 0)); render->pushMatrix(); render->translate(MVector3(getScroll().x, getScroll().y, 0)); // drawing unsigned int i; unsigned int oSize = m_objects.size(); for(i=0; i<oSize; i++) m_objects[i]->draw(); render->popMatrix(); // draw shadows if(hasShadow()) { render->disableScissorTest(); drawShadow(); render->enableScissorTest(); } // scolling slides if(isHorizontalScroll()) m_hScrollSlide.draw(); if(isVerticalScroll()) m_vScrollSlide.draw(); render->popMatrix(); }