void DAVA::ShadowVolumeNode::DrawShadow() { Matrix4 prevMatrix = RenderManager::Instance()->GetMatrix(RenderManager::MATRIX_MODELVIEW); Matrix4 meshFinalMatrix = GetWorldTransform() * prevMatrix; RenderManager::Instance()->SetMatrix(RenderManager::MATRIX_MODELVIEW, meshFinalMatrix); Matrix4 projMatrix = RenderManager::Instance()->GetMatrix(RenderManager::MATRIX_PROJECTION); RenderManager::Instance()->SetShader(shader); RenderManager::Instance()->SetRenderData(shadowPolygonGroup->renderDataObject); RenderManager::Instance()->FlushState(); RenderManager::Instance()->AttachRenderData(); Vector3 position = Vector3() * GetWorldTransform(); Light * light = scene->GetNearestDynamicLight(Light::TYPE_COUNT, position); if (light && uniformLightPosition0 != -1) { Vector3 lightPosition0 = light->GetPosition(); const Matrix4 & matrix = scene->GetCurrentCamera()->GetMatrix(); lightPosition0 = lightPosition0 * matrix; shader->SetUniformValueByIndex(uniformLightPosition0, lightPosition0); } if (shadowPolygonGroup->renderDataObject->GetIndexBufferID() != 0) { RenderManager::Instance()->HWDrawElements(PRIMITIVETYPE_TRIANGLELIST, shadowPolygonGroup->indexCount, EIF_16, 0); } else { RenderManager::Instance()->HWDrawElements(PRIMITIVETYPE_TRIANGLELIST, shadowPolygonGroup->indexCount, EIF_16, shadowPolygonGroup->indexArray); } RenderManager::Instance()->SetMatrix(RenderManager::MATRIX_MODELVIEW, prevMatrix); }
void CannonTower::Fire(){ //Get closest enemy Enemy * enemy = mGame.GetWorld().GetClosestEnemy(GetWorldTransform().GetTranslation()); if (enemy == nullptr) return; //Turn to enemy direction SetRotation(0); Vector3 enemyDir = enemy->GetPosition() - GetWorldTransform().GetTranslation(); enemyDir.Normalize(); Vector3 towerPos = GetWorldTransform().GetTranslation(); float angle = Math::Acos(Dot(enemyDir, Vector3::UnitX)); float crossZ = Cross(Vector3::UnitX, enemyDir).z; if (crossZ < 0.0f){ angle *= -1.0f; } SetRotation(angle); //Fire the ball auto ball = CannonBall::Spawn(mGame); ball->SetPosition(GetWorldTransform().GetTranslation()); ball->SetRotation(angle); //Trigger the sound mAudio->PlaySound(mShottingSound); }
void KTraceEMF::CompareDC(HDC hDC) { Compare(m_value[0], GetMapMode(hDC), "MapMode : %d\r\n"); Compare(m_value[1], GetGraphicsMode(hDC), "GraphicsMode : %d\r\n"); XFORM xm; GetWorldTransform(hDC, & xm); Compare(m_float[0], xm.eM11, "WT.eM11 : %8.5f\r\n"); Compare(m_float[1], xm.eM12, "WT.eM12 : %8.5f\r\n"); Compare(m_float[2], xm.eM21, "WT.eM21 : %8.5f\r\n"); Compare(m_float[3], xm.eM22, "WT.eM22 : %8.5f\r\n"); Compare(m_float[4], xm.eDx, "WT.eDx : %8.5f\r\n"); Compare(m_float[5], xm.eDy, "WT.eDy : %8.5f\r\n"); Compare(m_value[2], GetBkMode(hDC), "BkMode : %d\r\n"); Compare(m_value[3], GetROP2(hDC), "ROP2 : %d\r\n"); Compare(m_value[4], ((int)GetTextAlign(hDC)), "TextAlign : 0x%x\r\n"); Compare(m_object[0], GetCurrentObject(hDC, OBJ_PEN), "Pen : 0x%08x\r\n"); Compare(m_object[1], GetCurrentObject(hDC, OBJ_BRUSH), "Brush : 0x%08x\r\n"); Compare(m_object[2], GetCurrentObject(hDC, OBJ_FONT), "Font : 0x%08x\r\n"); Compare(m_object[3], GetCurrentObject(hDC, OBJ_PAL), "Palette : 0x%08x\r\n"); Compare(m_object[4], GetCurrentObject(hDC, OBJ_COLORSPACE), "ColorSpace : 0x%08x\r\n"); Compare(m_object[5], GetCurrentObject(hDC, OBJ_BITMAP), "Bitmap : 0x%08x\r\n"); }
void LindenmayerTreeNode::Render(OGLRenderer& r, bool render_children) { if (r.GetCurrentShader() != shader) r.SetCurrentShader(shader); r.UpdateShaderMatrices(); Matrix4 transform = GetWorldTransform() * Matrix4::Scale(GetModelScale()); glUniformMatrix4fv(glGetUniformLocation(GetShader()->GetProgram(), "modelMatrix"), 1, false, (float*)&transform); glUniformMatrix4fv(glGetUniformLocation(GetShader()->GetProgram(), "textureMatrix"), 1, false, (float*)&GetTextureMatrix()); glUniform4fv(glGetUniformLocation(GetShader()->GetProgram(), "nodeColour"), 1, (float*)&GetColour()); /*Draw the branches first to reduce expensive BindTexture calls*/ glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0].id); for (auto it = children.begin(); it != children.end(); ++it) { mem_usage += sizeof(LBranchNode); (*it)->Render(r, false); } /*Then draw the "leaves", turning off alpha blending to do so*/ glBindTexture(GL_TEXTURE_2D, textures[1].id); glDisable(GL_BLEND); for (auto it = children.begin(); it != children.end(); ++it) { for (auto it2 = (*it)->GetChildIteratorStart(); it2 != (*it)->GetChildIteratorEnd(); ++it2) { mem_usage += sizeof(LLeafNode) + sizeof(ParticleEmitter); (*it2)->Render(r, false); } } glEnable(GL_BLEND); }
void MacPrinterCanvas::start(float scale) { static char szMsg[] = "NEURON"; scale_ = scale; if (!get()) { return; } //if (!Escape(hdc, STARTDOC, sizeof szMsg-1, szMsg, NULL)) { //DebugMessage("STARTDOC failed\n"); // abort(); //} DOCINFO di; di.cbSize = sizeof(DOCINFO); di.lpszDocName = "NEURON"; di.lpszOutput = NULL; StartDoc(hdc, &di); StartPage(hdc); // SetMapMode(hdc, MM_TWIPS); int a = GetMapMode(hdc); SIZE b; GetViewportExtEx(hdc, &b); POINT c; GetViewportOrgEx(hdc, &c); XFORM d; GetWorldTransform(hdc, &d); if (a < -10) { return; } damage_all(); RECT r; //SetRectRgn(&r, 0, 0, hres_/2, vres_/2); r.left = 0; r.top=0; r.right = hres_; r.bottom=vres_; beginPaint(hdc, r); //SelectClipRgn(hdc, NULL); //d.eM11 = d.eM22 *= 2.; //SetWorldTransform(hdc, &d); }
bool SG_Spatial::inside(const MT_Point3 &point) const { MT_Scalar radius = m_worldScaling[m_worldScaling.closestAxis()]*m_radius; return (m_worldPosition.distance2(point) <= radius*radius) ? m_bbox.transform(GetWorldTransform()).inside(point) : false; }
void DIBPixelData::setRGBABitmapAlpha(HDC hdc, const IntRect& dstRect, unsigned char level) { HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)); DIBPixelData pixelData(bitmap); ASSERT(pixelData.bitsPerPixel() == 32); IntRect drawRect(dstRect); XFORM trans; GetWorldTransform(hdc, &trans); IntSize transformedPosition(trans.eDx, trans.eDy); drawRect.move(transformedPosition); int pixelDataWidth = pixelData.size().width(); int pixelDataHeight = pixelData.size().height(); IntRect bitmapRect(0, 0, pixelDataWidth, pixelDataHeight); drawRect.intersect(bitmapRect); if (drawRect.isEmpty()) return; RGBQUAD* bytes = reinterpret_cast<RGBQUAD*>(pixelData.buffer()); bytes += drawRect.y() * pixelDataWidth; size_t width = drawRect.width(); size_t height = drawRect.height(); int x = drawRect.x(); for (size_t i = 0; i < height; i++) { RGBQUAD* p = bytes + x; for (size_t j = 0; j < width; j++) { p->rgbReserved = level; p++; } bytes += pixelDataWidth; } }
void _cairo_win32_display_surface_unset_clip (cairo_win32_display_surface_t *surface) { XFORM saved_xform; int gm = GetGraphicsMode (surface->win32.dc); if (gm == GM_ADVANCED) { GetWorldTransform (surface->win32.dc, &saved_xform); ModifyWorldTransform (surface->win32.dc, NULL, MWT_IDENTITY); } /* initial_clip_rgn will either be a real region or NULL (which means reset to no clip region) */ SelectClipRgn (surface->win32.dc, surface->initial_clip_rgn); if (surface->had_simple_clip) { /* then if we had a simple clip, intersect */ IntersectClipRect (surface->win32.dc, surface->win32.extents.x, surface->win32.extents.y, surface->win32.extents.x + surface->win32.extents.width, surface->win32.extents.y + surface->win32.extents.height); } if (gm == GM_ADVANCED) SetWorldTransform (surface->win32.dc, &saved_xform); }
void cScreenCapture::Render(Vector3 e_vPos,int e_iWidth,int e_iHeight) { if( m_uiWidth == -1 ) return; glBindTexture( GL_TEXTURE_2D, m_uiTextureID); e_iWidth /= 2; e_iHeight /= 2; float l_fTexPointer[] = { 0,1, 1,1, 0,0, 1,0}; float l_Vertices[] = { (float)-e_iWidth,(float)-e_iHeight,0, (float)e_iWidth, (float)-e_iHeight,0, (float)-e_iWidth, (float)e_iHeight,0, (float)e_iWidth,(float)e_iHeight,0}; cMatrix44 l_mat = cMatrix44::TranslationMatrix(Vector3((float)(e_vPos.x+e_iWidth),(float)(e_vPos.y+e_iHeight), e_vPos.z)); SetupShaderWorldMatrix(l_mat*GetWorldTransform()); myGlVertexPointer(3,l_Vertices); myGlUVPointer(2,l_fTexPointer); ASSIGN_2D_COLOR(Vector4::One); MY_GLDRAW_ARRAYS(GL_TRIANGLE_STRIP, 0, 4); }
void StencilEffects::RenderPlayfieldEffect() { if (!GAMECONTEXT) return; auto playfield = PLAYFIELD.Get(); if (!playfield) return; if (!m_bPlayfieldEffectVisible) return; GraphicsDriver::Instance()->SetTransform(GraphicsDriver::TS_World, playfield->GetWorldTransform()); if (m_TilesVB.IsValid()) { // Fill stencil with 1s GraphicsDriver::Instance()->SetStencilFunc(GraphicsDriver::CF_Always, 1, 0xff); GraphicsDriver::Instance()->SetStencilOps(GraphicsDriver::SO_Keep, GraphicsDriver::SO_Keep, GraphicsDriver::SO_Replace); m_TilesMaterial->Begin(); m_TilesMaterial->GetShader()->GetConstant("uAmbientColor")->Set(&Color::White, 1); m_TilesMaterial->GetShader()->Begin(); m_TilesVB->Begin(m_TilesMaterial->GetShader()); m_TilesVB->Draw(); } GraphicsDriver::Instance()->SetRenderState(GraphicsDriver::RS_StencilWriting, 0); // no more writing into the stencil buffer GraphicsDriver::Instance()->SetStencilFunc(GraphicsDriver::CF_NotEqual, 1, 0xff); // Render only where stencil is not 1 m_DefaultMaterial->Begin(); m_DefaultMaterial->GetShader()->GetConstant("uAmbientColor")->Set(&m_PlayfieldHighlight, 1); m_DefaultMaterial->GetShader()->Begin(); m_PlayfieldVB->Begin(m_DefaultMaterial->GetShader()); m_PlayfieldVB->Draw(); }
void DynamicEntityNode::DynamicMove(sf::Vector2f Disp, bool SweepBothDirections) { unsigned int CollisionMask = eCollisionGroup::Monster | eCollisionGroup::Static | eCollisionGroup::Player | eCollisionGroup::Pickup; float SweepTmax = 1.5f; if (SweepBothDirections) { if (Disp.x != 0.0f) { HitInfo Hit; GetWorld()->GetQuadTree()->SweepShapeClosest(*GetCollisionShape(), GetWorldTransform(), sf::Vector2f(Disp.x, 0.0f), SweepTmax, CollisionMask, this, Hit); if (Hit.m_pObject) { Disp.x = 0.0f; OnTouch(Hit.m_pObject); } } if (Disp.y != 0.0f) { HitInfo Hit; GetWorld()->GetQuadTree()->SweepShapeClosest(*GetCollisionShape(), GetWorldTransform(), sf::Vector2f(0.0f, Disp.y), SweepTmax, CollisionMask, this, Hit); if (Hit.m_pObject) { Disp.y = 0.0f; OnTouch(Hit.m_pObject); } } } else { HitInfo Hit; GetWorld()->GetQuadTree()->SweepShapeClosest(*GetCollisionShape(), GetWorldTransform(), Disp, SweepTmax, CollisionMask, this, Hit); if (Hit.m_pObject) { Disp.x = 0.0f; Disp.y = 0.0f; OnTouch(Hit.m_pObject); } } Move(Disp); }
void FrostTower::FrostEnemies(){ //Get the near enemies vector std::vector<Enemy *> enemies = mGame.GetWorld().GetEnemiesInRange(GetWorldTransform().GetTranslation(), 100.0f); for (Enemy * enemy : enemies){ enemy->Slow(); } }
static cairo_int_status_t _cairo_win32_save_initial_clip (HDC hdc, cairo_win32_display_surface_t *surface) { RECT rect; int clipBoxType; int gm; XFORM saved_xform; /* GetClipBox/GetClipRgn and friends interact badly with a world transform * set. GetClipBox returns values in logical (transformed) coordinates; * it's unclear what GetClipRgn returns, because the region is empty in the * case of a SIMPLEREGION clip, but I assume device (untransformed) coordinates. * Similarly, IntersectClipRect works in logical units, whereas SelectClipRgn * works in device units. * * So, avoid the whole mess and get rid of the world transform * while we store our initial data and when we restore initial coordinates. * * XXX we may need to modify x/y by the ViewportOrg or WindowOrg * here in GM_COMPATIBLE; unclear. */ gm = GetGraphicsMode (hdc); if (gm == GM_ADVANCED) { GetWorldTransform (hdc, &saved_xform); ModifyWorldTransform (hdc, NULL, MWT_IDENTITY); } clipBoxType = GetClipBox (hdc, &rect); if (clipBoxType == ERROR) { _cairo_win32_print_gdi_error (__FUNCTION__); SetGraphicsMode (hdc, gm); /* XXX: Can we make a more reasonable guess at the error cause here? */ return _cairo_error (CAIRO_STATUS_DEVICE_ERROR); } surface->win32.extents.x = rect.left; surface->win32.extents.y = rect.top; surface->win32.extents.width = rect.right - rect.left; surface->win32.extents.height = rect.bottom - rect.top; surface->initial_clip_rgn = NULL; surface->had_simple_clip = FALSE; if (clipBoxType == COMPLEXREGION) { surface->initial_clip_rgn = CreateRectRgn (0, 0, 0, 0); if (GetClipRgn (hdc, surface->initial_clip_rgn) <= 0) { DeleteObject(surface->initial_clip_rgn); surface->initial_clip_rgn = NULL; } } else if (clipBoxType == SIMPLEREGION) { surface->had_simple_clip = TRUE; } if (gm == GM_ADVANCED) SetWorldTransform (hdc, &saved_xform); return CAIRO_STATUS_SUCCESS; }
//------------------------------------------------------------------------ // Update the vegetation object. //------------------------------------------------------------------------ void etVegetationObject::UpdateObject(void) { if( m_Type == VGT_MESH && m_nDirtyState != m_pMesh->GetDirtyState() ) Reinitialize(); m_WorldBBox = m_Bounds; m_WorldBBox.TransformBox( GetWorldTransform() ); }
KFbxXMatrix FilmboxNode::GetLocalTransform( int frame ) const { KFbxXMatrix world_transform = GetWorldTransform( frame ); KFbxXMatrix parent_transform = GetParentWorldTransform( frame ); KFbxXMatrix world_to_local = parent_transform.Inverse(); KFbxXMatrix local_transform = world_to_local * world_transform; return local_transform; }
//---------------------------------------------------------------- /// Get World Orientation /// /// @return Orientation quaternion relative to parent //---------------------------------------------------------------- const Quaternion& Transform::GetWorldOrientation() const { if(mpParentTransform) { mqWorldOrientation = Core::Quaternion(GetWorldTransform()); return mqWorldOrientation; } return mqOrientation; }
//---------------------------------------------------------------- /// Get World Position /// /// @return The relative position of the object //---------------------------------------------------------------- const Vector3& Transform::GetWorldPosition() const { if(mpParentTransform) { mvWorldPosition = GetWorldTransform().GetTranslation(); return mvWorldPosition; } return mvPosition; }
//------------------------------------------------------------------------ // Update the terrain tile for the terrain level. //------------------------------------------------------------------------ void etTile::UpdateObject(void) { m_WorldBBox = m_Bounds; m_WorldBBox.TransformBox( GetWorldTransform() ); if( m_bModified ) { UpdateHeightData(); m_pSelected->BuildGeometry(); m_bModified = false; } }
void PolyDataObject::ObjectAddedToScene() { connect( GetManager(), SIGNAL(ReferenceObjectChanged()), this, SLOT(OnReferenceChanged()) ); connect( GetManager(), SIGNAL(ReferenceTransformChanged()), this, SLOT(OnReferenceChanged()) ); connect( GetManager(), SIGNAL(CursorPositionChanged()), this, SLOT(OnCursorPositionChanged()) ); connect( GetManager(), SIGNAL(StartCursorInteraction()), this, SLOT(OnStartCursorInteraction()) ); connect( GetManager(), SIGNAL(EndCursorInteraction()), this, SLOT(OnEndCursorInteraction()) ); m_referenceToPolyTransform->Identity(); m_referenceToPolyTransform->Concatenate( GetWorldTransform() ); m_referenceToPolyTransform->Concatenate( GetManager()->GetInverseReferenceTransform() ); UpdateCuttingPlane(); UpdateClippingPlanes(); }
void Node::SetParent(Node* parent) { if (parent) { Vector3 worldPosition; Quaternion worldRotation; Vector3 worldScale; GetWorldTransform().Decompose(worldPosition, worldRotation, worldScale); parent->AddChild(this); SetWorldTransform(worldPosition, worldRotation, worldScale); } }
bool HesperisIO::CreateCurveGroup(MDagPathArray & paths, CurveGroup * dst) { MStatus stat; const unsigned n = paths.length(); unsigned i, j; int numCvs = 0; unsigned numNodes = 0; for(i=0; i< n; i++) { if(!IsCurveValid(paths[i])) continue; MFnNurbsCurve fcurve(paths[i].node()); numCvs += fcurve.numCVs(); numNodes++; } if(numCvs < 4) { MGlobal::displayInfo(" too fews cvs!"); return false; } dst->create(numNodes, numCvs); Vector3F * pnts = dst->points(); unsigned * counts = dst->counts(); unsigned inode = 0; unsigned icv = 0; unsigned nj; MPoint wp; MMatrix worldTm; for(i=0; i< n; i++) { if(!IsCurveValid(paths[i])) continue; worldTm = GetWorldTransform(paths[i]); MFnNurbsCurve fcurve(paths[i].node()); nj = fcurve.numCVs(); MPointArray ps; fcurve.getCVs(ps, MSpace::kWorld); counts[inode] = nj; inode++; for(j=0; j<nj; j++) { wp = ps[j] * worldTm; pnts[icv].set((float)wp.x, (float)wp.y, (float)wp.z); icv++; } } return true; }
bool HesperisPolygonalMeshIO::CreateMeshData(APolygonalMesh * data, const MDagPath & path) { MGlobal::displayInfo(MString("todo poly mesh write ")+path.fullPathName()); MStatus stat; MFnMesh fmesh(path.node(), &stat); if(!stat) { MGlobal::displayInfo(MString(" not a mesh ") + path.fullPathName()); return false; } unsigned np = fmesh.numVertices(); unsigned nf = fmesh.numPolygons(); unsigned ni = fmesh.numFaceVertices(); data->create(np, ni, nf); Vector3F * pnts = data->points(); unsigned * inds = data->indices(); unsigned * cnts = data->faceCounts(); MPointArray ps; MPoint wp; MMatrix worldTm; worldTm = GetWorldTransform(path); fmesh.getPoints(ps, MSpace::kObject); unsigned i = 0; for(;i<np;i++) { wp = ps[i] * worldTm; pnts[i].set((float)wp.x, (float)wp.y, (float)wp.z); } unsigned j; unsigned acc = 0; MIntArray vertices; MItMeshPolygon faceIt(path); for(i=0; !faceIt.isDone(); faceIt.next(), i++) { cnts[i] = faceIt.polygonVertexCount(); faceIt.getVertices(vertices); for(j = 0; j < vertices.length(); j++) { inds[acc] = vertices[j]; acc++; } } data->computeFaceDrift(); return true; }
void CPlayer::Render( CRenderEngine &rndr ) { /* Debug: draw a small white sphere at the player's position */ Sphere_PosRad s; s.radius = 0.15f; s.pos = m_transform.GetTranslation(); s.pos.y += 0.5f * s.radius; Color_4 c; c.a = 1.0f; c.r = 0.3f; c.g = 0.3f; c.b = 1.0f; rndr.DrawDebugSphere(s, c); /* Draw Player Model */ m_pModel->SetRenderFunc(m_pModel->RenderFuncs.lightAndTexture); m_pModel->Render( rndr, GetWorldTransform(), rndr.GetShaderManager() ); }
void DebugNode::Draw() { Entity::Draw(); if (!isDraw) return; if (verts.size() == 0) return; Matrix4 prevMatrix = RenderManager::Instance()->GetMatrix(RenderManager::MATRIX_MODELVIEW); Matrix4 meshFinalMatrix = GetWorldTransform() * prevMatrix; RenderManager::Instance()->SetMatrix(RenderManager::MATRIX_MODELVIEW, meshFinalMatrix); RenderManager::Instance()->SetRenderEffect(RenderManager::FLAT_COLOR); RenderManager::Instance()->SetRenderData(renderData); RenderManager::Instance()->DrawArrays(PRIMITIVETYPE_LINELIST, 0, verts.size()/3); RenderManager::Instance()->SetMatrix(RenderManager::MATRIX_MODELVIEW, prevMatrix); }
void SceneManager::UpdateRenderData(std::map<unsigned int, SceneNode *> nodes) const { // for each node for (auto iter : nodes) { // check this node auto node = iter.second; // prep the world transform for this node Matrix world_transform = node->GetWorldTransform(); Light * pLight = node->GetLight(); // make render data for this node if (RenderSet * rs = node->GetRenderSet()) { rs->worldTransform = world_transform; // if this renderable has a light attached // then it emits light and should use a different // shader rs->emitsLight = node->EmitsLight(); // set the render sets material rs->material = node->GetMaterial(); } // see if it is a light if (pLight != nullptr) { pLight->worldTransform = world_transform; } // recurse each child node this->UpdateRenderData(node->GetChildren()); } }
void BMaxObject::LoadPhysics() { if (m_dwPhysicsMethod > 0 && IsPhysicsEnabled() && (GetStaticActorCount() == 0)) { if (m_pAnimatedMesh && m_pAnimatedMesh->IsLoaded()) { CParaXModel* ppMesh = m_pAnimatedMesh->GetModel(); if (ppMesh == 0 || ppMesh->GetHeader().maxExtent.x <= 0.f) { EnablePhysics(false); // disable physics forever, if failed loading physics data return; } // get world transform matrix Matrix4 mxWorld; GetWorldTransform(mxWorld); IParaPhysicsActor* pActor = CGlobals::GetPhysicsWorld()->CreateStaticMesh(m_pAnimatedMesh.get(), mxWorld, m_nPhysicsGroup, &m_staticActors, this); if (m_staticActors.empty()) { // disable physics forever, if no physics actors are loaded. EnablePhysics(false); } } } }
void LodNode::RecheckLod() { //#define LOD_DEBUG if (!currentLod)return; if (INVALID_LOD_LAYER != forceLodLayer) { for (List<LodData>::iterator it = lodLayers.begin(); it != lodLayers.end(); it++) { if (it->layer >= forceLodLayer) { currentLod = &(*it); return; } } return; } #ifdef LOD_DEBUG int32 cl = currentLod->layer; #endif { float32 dst = 0.f; if(INVALID_DISTANCE == forceDistance) { if(scene->GetCurrentCamera()) { dst = (scene->GetCurrentCamera()->GetPosition() - GetWorldTransform().GetTranslationVector()).SquareLength(); dst *= scene->GetCurrentCamera()->GetZoomFactor() * scene->GetCurrentCamera()->GetZoomFactor(); } } else { dst = forceDistanceSq; } if (dst > GetLodLayerFarSquare(currentLod->layer) || dst < GetLodLayerNearSquare(currentLod->layer)) { for (List<LodData>::iterator it = lodLayers.begin(); it != lodLayers.end(); it++) { if (dst >= GetLodLayerNearSquare(it->layer)) { currentLod = &(*it); } else { #ifdef LOD_DEBUG if (cl != currentLod->layer) { Logger::Info("Switch lod to %d", currentLod->layer); } #endif return; } } } } #ifdef LOD_DEBUG if (cl != currentLod->layer) { Logger::Info("Switch lod to %d", currentLod->layer); } #endif }
void SG_Spatial::getAABBox(MT_Point3 *box) const { m_bbox.getaa(box, GetWorldTransform()); }
HDC gfxWindowsNativeDrawing::BeginNativeDrawing() { if (mRenderState == RENDER_STATE_INIT) { nsRefPtr<gfxASurface> surf; if (mContext->GetCairo()) { surf = mContext->CurrentSurface(&mDeviceOffset.x, &mDeviceOffset.y); } if (surf && surf->CairoStatus()) return nsnull; gfxMatrix m = mContext->CurrentMatrix(); if (!m.HasNonTranslation()) mTransformType = TRANSLATION_ONLY; else if (m.HasNonAxisAlignedTransform()) mTransformType = COMPLEX; else mTransformType = AXIS_ALIGNED_SCALE; // if this is a native win32 surface, we don't have to // redirect rendering to our own HDC; in some cases, // we may be able to use the HDC from the surface directly. if (surf && ((surf->GetType() == gfxASurface::SurfaceTypeWin32 || surf->GetType() == gfxASurface::SurfaceTypeWin32Printing) && (surf->GetContentType() == gfxASurface::CONTENT_COLOR || (surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA && (mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA))))) { // grab the DC. This can fail if there is a complex clipping path, // in which case we'll have to fall back. mWinSurface = static_cast<gfxWindowsSurface*>(static_cast<gfxASurface*>(surf.get())); mDC = mWinSurface->GetDCWithClip(mContext); if (mDC) { if (mTransformType == TRANSLATION_ONLY) { mRenderState = RENDER_STATE_NATIVE_DRAWING; mTranslation = m.GetTranslation(); } else if (((mTransformType == AXIS_ALIGNED_SCALE) && (mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) || (mNativeDrawFlags & CAN_COMPLEX_TRANSFORM)) { mWorldTransform.eM11 = (FLOAT) m.xx; mWorldTransform.eM12 = (FLOAT) m.yx; mWorldTransform.eM21 = (FLOAT) m.xy; mWorldTransform.eM22 = (FLOAT) m.yy; mWorldTransform.eDx = (FLOAT) m.x0; mWorldTransform.eDy = (FLOAT) m.y0; mRenderState = RENDER_STATE_NATIVE_DRAWING; } } } // If we couldn't do native drawing, then we have to do two-buffer drawing // and do alpha recovery if (mRenderState == RENDER_STATE_INIT) { mRenderState = RENDER_STATE_ALPHA_RECOVERY_BLACK; // We round out our native rect here, that way the snapping will // happen correctly. mNativeRect.RoundOut(); // we only do the scale bit if we can do an axis aligned // scale; otherwise we scale (if necessary) after // rendering with cairo. Note that if we're doing alpha recovery, // we cannot do a full complex transform with win32 (I mean, we could, but // it would require more code that's not here.) if (mTransformType == TRANSLATION_ONLY || !(mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) { mScale = gfxSize(1.0, 1.0); // Add 1 to the surface size; it's guaranteed to not be incorrect, // and it fixes bug 382458 // There's probably a better fix, but I haven't figured out // the root cause of the problem. mTempSurfaceSize = gfxIntSize((PRInt32) ceil(mNativeRect.Width() + 1), (PRInt32) ceil(mNativeRect.Height() + 1)); } else { // figure out the scale factors mScale = m.ScaleFactors(true); mWorldTransform.eM11 = (FLOAT) mScale.width; mWorldTransform.eM12 = 0.0f; mWorldTransform.eM21 = 0.0f; mWorldTransform.eM22 = (FLOAT) mScale.height; mWorldTransform.eDx = 0.0f; mWorldTransform.eDy = 0.0f; // See comment above about "+1" mTempSurfaceSize = gfxIntSize((PRInt32) ceil(mNativeRect.Width() * mScale.width + 1), (PRInt32) ceil(mNativeRect.Height() * mScale.height + 1)); } } } if (mRenderState == RENDER_STATE_NATIVE_DRAWING) { // we can just do native drawing directly to the context's surface // do we need to use SetWorldTransform? if (mTransformType != TRANSLATION_ONLY) { SetGraphicsMode(mDC, GM_ADVANCED); GetWorldTransform(mDC, &mOldWorldTransform); SetWorldTransform(mDC, &mWorldTransform); } GetViewportOrgEx(mDC, &mOrigViewportOrigin); SetViewportOrgEx(mDC, mOrigViewportOrigin.x + (int)mDeviceOffset.x, mOrigViewportOrigin.y + (int)mDeviceOffset.y, NULL); return mDC; } else if (mRenderState == RENDER_STATE_ALPHA_RECOVERY_BLACK || mRenderState == RENDER_STATE_ALPHA_RECOVERY_WHITE) { // we're going to use mWinSurface to create our temporary surface here // get us a RGB24 DIB; DIB is important, because // we can later call GetImageSurface on it. mWinSurface = new gfxWindowsSurface(mTempSurfaceSize); mDC = mWinSurface->GetDC(); RECT r = { 0, 0, mTempSurfaceSize.width, mTempSurfaceSize.height }; if (mRenderState == RENDER_STATE_ALPHA_RECOVERY_BLACK) FillRect(mDC, &r, (HBRUSH)GetStockObject(BLACK_BRUSH)); else FillRect(mDC, &r, (HBRUSH)GetStockObject(WHITE_BRUSH)); if ((mTransformType != TRANSLATION_ONLY) && (mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) { SetGraphicsMode(mDC, GM_ADVANCED); SetWorldTransform(mDC, &mWorldTransform); } return mDC; } else { NS_ERROR("Bogus render state!"); return nsnull; } }
static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) { Color fillColor = graphicsContext->fillColor(); bool drawIntoBitmap = false; TextDrawingModeFlags drawingMode = graphicsContext->textDrawingMode(); if (drawingMode == TextModeFill) { if (!fillColor.alpha()) return; drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer(); if (!drawIntoBitmap) { FloatSize offset; float blur; Color color; ColorSpace shadowColorSpace; graphicsContext->getShadow(offset, blur, color, shadowColorSpace); drawIntoBitmap = offset.width() || offset.height() || blur; } } // We have to convert CG's two-dimensional floating point advances to just horizontal integer advances. Vector<int, 2048> gdiAdvances; int totalWidth = 0; for (int i = 0; i < numGlyphs; i++) { gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i))); totalWidth += gdiAdvances[i]; } HDC hdc = 0; OwnPtr<GraphicsContext::WindowsBitmap> bitmap; IntRect textRect; if (!drawIntoBitmap) hdc = graphicsContext->getWindowsContext(textRect, true, false); if (!hdc) { drawIntoBitmap = true; // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges. // FIXME: Can get glyphs' optical bounds (even from CG) to get this right. const FontMetrics& fontMetrics = font->fontMetrics(); int lineGap = fontMetrics.lineGap(); textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2, point.y() - fontMetrics.ascent() - lineGap, totalWidth + fontMetrics.ascent() + fontMetrics.descent(), fontMetrics.lineSpacing()); bitmap = graphicsContext->createWindowsBitmap(textRect.size()); memset(bitmap->buffer(), 255, bitmap->bufferLength()); hdc = bitmap->hdc(); XFORM xform; xform.eM11 = 1.0f; xform.eM12 = 0.0f; xform.eM21 = 0.0f; xform.eM22 = 1.0f; xform.eDx = -textRect.x(); xform.eDy = -textRect.y(); SetWorldTransform(hdc, &xform); } SelectObject(hdc, font->platformData().hfont()); // Set the correct color. if (drawIntoBitmap) SetTextColor(hdc, RGB(0, 0, 0)); else SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue())); SetBkMode(hdc, TRANSPARENT); SetTextAlign(hdc, TA_LEFT | TA_BASELINE); // Uniscribe gives us offsets to help refine the positioning of combining glyphs. FloatSize translation = glyphBuffer.offsetAt(from); if (translation.width() || translation.height()) { XFORM xform; xform.eM11 = 1.0; xform.eM12 = 0; xform.eM21 = 0; xform.eM22 = 1.0; xform.eDx = translation.width(); xform.eDy = translation.height(); ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); } if (drawingMode == TextModeFill) { XFORM xform; xform.eM11 = 1.0; xform.eM12 = 0; xform.eM21 = font->platformData().syntheticOblique() ? -tanf(syntheticObliqueAngle * piFloat / 180.0f) : 0; xform.eM22 = 1.0; xform.eDx = point.x(); xform.eDy = point.y(); ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data()); if (font->syntheticBoldOffset()) { xform.eM21 = 0; xform.eDx = font->syntheticBoldOffset(); xform.eDy = 0; ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data()); } } else { XFORM xform; GetWorldTransform(hdc, &xform); AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy); CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity; if (font->platformData().syntheticOblique()) initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0)); initialGlyphTransform.tx = 0; initialGlyphTransform.ty = 0; CGContextRef cgContext = graphicsContext->platformContext(); CGContextSaveGState(cgContext); BOOL fontSmoothingEnabled = false; SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0); CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled); CGContextScaleCTM(cgContext, 1.0, -1.0); CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height())); for (unsigned i = 0; i < numGlyphs; ++i) { RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i))); CGContextSaveGState(cgContext); CGContextConcatCTM(cgContext, initialGlyphTransform); if (drawingMode & TextModeFill) { CGContextAddPath(cgContext, glyphPath.get()); CGContextFillPath(cgContext); if (font->syntheticBoldOffset()) { CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0); CGContextAddPath(cgContext, glyphPath.get()); CGContextFillPath(cgContext); CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0); } } if (drawingMode & TextModeStroke) { CGContextAddPath(cgContext, glyphPath.get()); CGContextStrokePath(cgContext); if (font->syntheticBoldOffset()) { CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0); CGContextAddPath(cgContext, glyphPath.get()); CGContextStrokePath(cgContext); CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0); } } CGContextRestoreGState(cgContext); CGContextTranslateCTM(cgContext, gdiAdvances[i], 0); } CGContextRestoreGState(cgContext); } if (drawIntoBitmap) { UInt8* buffer = bitmap->buffer(); unsigned bufferLength = bitmap->bufferLength(); for (unsigned i = 0; i < bufferLength; i += 4) { // Use green, which is always in the middle. UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255; buffer[i] = fillColor.blue(); buffer[i + 1] = fillColor.green(); buffer[i + 2] = fillColor.red(); buffer[i + 3] = alpha; } graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location()); } else graphicsContext->releaseWindowsContext(hdc, textRect, true, false); }