void ClustMod::GetWorldBoundBox( TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) { // Need the correct bound box for proper damage rect calcs. #ifdef DESIGN_VER TimeValue rt = GetCOREInterface()->GetTime(); Matrix3 obtm = inode->GetObjectTM(rt); #else Matrix3 obtm = inode->GetObjectTM(t); #endif GraphicsWindow *gw = vpt->getGW(); Matrix3 ptm(1), ctm(1); if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE); if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE); //Matrix3 tm = DEFORMER_TM; Matrix3 tm = CompTM(ptm,ctm,mc->tm,1); ClustDeformer deformer(tm); BoxLineProc bp1(&obtm); DoModifiedBox(MakeBoxNotEmpty(*mc->box), deformer, bp1); box = bp1.Box(); //obtm = ctm * obtm; if (mc->tm) obtm = ctm * Inverse(*mc->tm) * obtm; else obtm = ctm * obtm; BoxLineProc bp2(&obtm); DrawCenterMark(bp2,MakeBoxNotEmpty(*mc->box)); box += bp2.Box(); }
void EditFaceDataMod::GetSubObjectTMs (SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) { if (!mc->localData) return; if (selLevel == SEL_OBJECT) return; // shouldn't happen. EditFaceDataModData *modData = (EditFaceDataModData *) mc->localData; Mesh *mesh = modData->GetCacheMesh(); MNMesh *mnmesh = modData->GetCacheMNMesh(); if (!mesh && !mnmesh) return; Matrix3 tm = node->GetObjectTM(t); Box3 box; if (mesh) { BitArray sel = mesh->VertexTempSel (); if (!sel.NumberSet()) return; for (int i=0; i<mesh->numVerts; i++) if (sel[i]) box += mesh->verts[i] * tm; } else { int numSel, which; float value; bool valueDetermined; modData->DescribeSelection (numSel, which, value, valueDetermined); if (!numSel) return; if (numSel==1) { for (int j=0; j<mnmesh->f[which].deg; j++) box += mnmesh->P(mnmesh->f[which].vtx[j]) * tm; } else { for (int i=0; i<mnmesh->numf; i++) { if (mnmesh->f[i].GetFlag (MN_DEAD)) continue; if (!modData->GetFaceSel()[i]) continue; for (int j=0; j<mnmesh->f[i].deg; j++) box += mnmesh->P(mnmesh->f[i].vtx[j]) * tm; } } } Matrix3 ctm(1); ctm.SetTrans (box.Center()); cb->TM (ctm,0); }
float Sphere::FindIntersection( const Ray & RayInst ) { Vec3 ro( RayInst.origin ); Vec3 rd( RayInst.direction ); Vec3 sc( center ); float rad = radius; Vec3 ctm( ro - sc ); float a = 1.0f; float b = DotProduct( ctm * 2.0f, rd ); float c = DotProduct( ctm, ctm ) - Sq( rad ); float disc = Sq( b ) - ( 4.0f * c ); float result = -1.0f; if( disc <= 0.0f ) { return result; } float root = ( ( -1.0f * b - sqrtf( disc ) ) * 0.5f ); result = root > 0.0f ? root : ( sqrtf( disc ) - b ) * 0.5f; return result; }
// RenderBox methods will expect coordinates w/o any transforms in coordinates // relative to our borderBox origin. This method gives us exactly that. AffineTransform RenderSVGRoot::localToBorderBoxTransform() const { IntSize borderAndPadding = borderOriginToContentBox(); SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); float scale = svg->currentScale(); AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width(), borderAndPadding.height()); ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y()); return svg->viewBoxToViewTransform(width(), height()) * ctm; }
// RenderBox methods will expect coordinates w/o any transforms in coordinates // relative to our borderBox origin. This method gives us exactly that. AffineTransform RenderSVGRoot::localToBorderBoxTransform() const { IntSize borderAndPadding = borderOriginToContentBox(); SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); float scale = style()->effectiveZoom(); FloatPoint translate = svg->currentTranslate(); AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y()); return ctm * svg->viewBoxToViewTransform(width() / scale, height() / scale); }
void ClustMod::GetSubObjectTMs( SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) { Matrix3 obtm = node->GetObjectTM(t); Matrix3 ptm(1), ctm(1); if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE); if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE); //Matrix3 tm = DEFORMER_TM * obtm; Matrix3 tm = CompTM(ptm,ctm,mc->tm,1) * obtm; cb->TM(tm,0); }
int ClustMod::Display( TimeValue t, INode* inode, ViewExp *vpt, int flags, ModContext *mc) { // Transform the gizmo with the node. #ifdef DESIGN_VER TimeValue rt = GetCOREInterface()->GetTime(); Matrix3 obtm = inode->GetObjectTM(rt); #else Matrix3 obtm = inode->GetObjectTM(t); #endif GraphicsWindow *gw = vpt->getGW(); gw->setTransform(obtm); Matrix3 ptm(1), ctm(1); if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE); if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE); //Matrix3 tm = DEFORMER_TM; Matrix3 tm = CompTM(ptm,ctm,mc->tm,1); ClustDeformer deformer(tm); if (ip && ip->GetSubObjectLevel() == 1) { //gw->setColor( LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor( LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } if (mc->box->pmin==mc->box->pmax) { Point3 pt = mc->box->pmin * tm; gw->marker(&pt,ASTERISK_MRKR); } else { DoModifiedBox(MakeBoxNotEmpty(*mc->box),deformer,DrawLineProc(gw)); } //obtm = ctm * obtm; if (mc->tm) obtm = ctm * Inverse(*mc->tm) * obtm; else obtm = ctm * obtm; gw->setTransform(obtm); if ( ip && (ip->GetSubObjectLevel() == 1 || ip->GetSubObjectLevel() == 2) ) { //gw->setColor( LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor( LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } DrawCenterMark(DrawLineProc(gw),MakeBoxNotEmpty(*mc->box)); return 0; }
void ClustMod::ModifyObject( TimeValue t, ModContext &mc, ObjectState * os, INode *node) { Interval valid = FOREVER; Matrix3 ptm(1), ctm(1); if (posControl) posControl->GetValue(t,&ptm,valid,CTRL_RELATIVE); if (tmControl) tmControl->GetValue(t,&ctm,valid,CTRL_RELATIVE); //Matrix3 tm = DEFORMER_TM; Matrix3 tm = CompTM(ptm,ctm,mc.tm,0); ClustDeformer deformer(tm); os->obj->Deform(&deformer, TRUE); os->obj->UpdateValidity(GEOM_CHAN_NUM,valid); }
int ClustMod::HitTest( TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { int savedLimits; Matrix3 obtm = inode->GetObjectTM(t); GraphicsWindow *gw = vpt->getGW(); HitRegion hr; MakeHitRegion(hr,type, crossing,4,p); gw->setHitRegion(&hr); gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); gw->clearHitCode(); gw->setTransform(obtm); Matrix3 ptm(1), ctm(1); if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE); if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE); if (ip && ip->GetSubObjectLevel() == 1) { //Matrix3 tm = DEFORMER_TM; Matrix3 tm = CompTM(ptm,ctm,mc->tm,1); ClustDeformer deformer(tm); if (mc->box->pmin==mc->box->pmax) { Point3 pt = mc->box->pmin * tm; gw->marker(&pt,ASTERISK_MRKR); } else { DoModifiedBox(MakeBoxNotEmpty(*mc->box),deformer,DrawLineProc(gw)); } } if (ip && (ip->GetSubObjectLevel() == 1 || ip->GetSubObjectLevel() == 2)) { //obtm = ctm * obtm; if (mc->tm) obtm = ctm * Inverse(*mc->tm) * obtm; else obtm = ctm * obtm; gw->setTransform(obtm); DrawCenterMark(DrawLineProc(gw),MakeBoxNotEmpty(*mc->box)); } gw->setRndLimits(savedLimits); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL); return 1; } return 0; }
int GusdOBJ_usdcamera::applyInputIndependentTransform(OP_Context& ctx, UT_DMatrix4& mx) { mx.identity(); fpreal t = ctx.getTime(); if(UsdGeomCamera cam = _LoadCamera(t, ctx.getThread())) { float frame = evalFloat(_frameIdx, 0, t); GfMatrix4d ctm(1.); bool stat = true; bool resetsXformStack = false; switch(evalInt("xformmode", 0, t)) { case _POSTMULTCTM_TRANSFORM: stat = true; ctm = cam.ComputeLocalToWorldTransform(frame); break; case _CTM_TRANSFORM: stat = true; ctm = cam.ComputeParentToWorldTransform(frame); break; case _OBJ_TRANSFORM: // XXX: how do we reset xformStack here? // Is that (or should that // be) handled by the Compute calls above? stat = cam.GetLocalTransformation(&ctm, &resetsXformStack, frame); break; default: // _IGNORE_TRANSFORM: stat = true; ctm.SetIdentity(); break; } if(!stat) { stealErrors(_errors, /*borrow*/ true); return 0; } mx = GusdUT_Gf::Cast(ctm); } return OBJ_Camera::applyInputIndependentTransform(ctx, mx); }
void ClustMod::GetSubObjectCenters( SubObjAxisCallback *cb,TimeValue t,INode *node,ModContext *mc) { Matrix3 obtm = node->GetObjectTM(t); Matrix3 ptm(1), ctm(1); if (posControl) posControl->GetValue(t,&ptm,FOREVER,CTRL_RELATIVE); if (tmControl) tmControl->GetValue(t,&ctm,FOREVER,CTRL_RELATIVE); if (cb->Type()==SO_CENTER_PIVOT) { //Matrix3 mat = ctm * obtm; Matrix3 mat; if (mc->tm) mat = ctm * Inverse(*mc->tm) * obtm; else mat = ctm * obtm; cb->Center(mat.GetTrans(),0); } else { //Matrix3 tm = DEFORMER_TM; Matrix3 tm = CompTM(ptm,ctm,mc->tm,1); ClustDeformer deformer(tm); BoxLineProc bp1(&obtm); DoModifiedBox(MakeBoxNotEmpty(*mc->box), deformer, bp1); cb->Center(bp1.Box().Center(),0); } }
FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CFX_PathData* pClippingPath) { if(textobj->m_nChars == 0) { return TRUE; } int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; if (text_render_mode == 3) { return TRUE; } CPDF_Font* pFont = textobj->m_TextState.GetFont(); if (pFont->GetFontType() == PDFFONT_TYPE3) { return ProcessType3Text(textobj, pObj2Device); } FX_BOOL bFill = FALSE, bStroke = FALSE, bClip = FALSE; if (pClippingPath) { bClip = TRUE; } else { switch (text_render_mode) { case 0: case 4: bFill = TRUE; break; case 1: case 5: if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { bFill = TRUE; } else { bStroke = TRUE; } break; case 2: case 6: if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { bFill = TRUE; } else { bFill = bStroke = TRUE; } break; case 3: case 7: return TRUE; default: bFill = TRUE; } } FX_ARGB stroke_argb = 0, fill_argb = 0; FX_BOOL bPattern = FALSE; if (bStroke) { if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { bPattern = TRUE; } else { stroke_argb = GetStrokeArgb(textobj); } } if (bFill) { if (textobj->m_ColorState.GetFillColor()->IsPattern()) { bPattern = TRUE; } else { fill_argb = GetFillArgb(textobj); } } CFX_AffineMatrix text_matrix; textobj->GetTextMatrix(&text_matrix); if(IsAvailableMatrix(text_matrix) == FALSE) { return TRUE; } FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); if (bPattern) { DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, &text_matrix, bFill, bStroke); return TRUE; } #if defined(_FPDFAPI_MINI_) if (bFill) { bStroke = FALSE; } if (bStroke) { if (font_size * text_matrix.GetXUnit() * pObj2Device->GetXUnit() < 6) { bStroke = FALSE; } } #endif if (bClip || bStroke) { const CFX_AffineMatrix* pDeviceMatrix = pObj2Device; CFX_AffineMatrix device_matrix; if (bStroke) { const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM; if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { CFX_AffineMatrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); text_matrix.ConcatInverse(ctm); device_matrix.Copy(ctm); device_matrix.Concat(*pObj2Device); pDeviceMatrix = &device_matrix; } } int flag = 0; if (bStroke && bFill) { flag |= FX_FILL_STROKE; flag |= FX_STROKE_TEXT_MODE; } #if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)textobj)->m_GeneralState; if (pGeneralData && pGeneralData->m_StrokeAdjust) { flag |= FX_STROKE_ADJUST; } #endif if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) { flag |= FXFILL_NOPATHSMOOTH; } return CPDF_TextRenderer::DrawTextPath(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, &text_matrix, pDeviceMatrix, textobj->m_GraphState, fill_argb, stroke_argb, pClippingPath, flag); } text_matrix.Concat(*pObj2Device); return CPDF_TextRenderer::DrawNormalText(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, &text_matrix, fill_argb, &m_Options); }
CSCADString CFolderListCtrl::TimeToStr( time_t ftm ) const { CTime ctm( ftm ); return ctm.Format( m_sModifiedFormat ); }
/** * Update derived data before operations. * The purpose of this call is to recompute internal data which depends * on the attributes of the object, but is not directly settable by the user. * Precomputing this data speeds up later rendering, because some items * can be omitted. * * Currently this method handles updating the visual and geometric bounding boxes * in pixels, storing the total transformation from item space to the screen * and cache invalidation. * * @param area Area to which the update should be restricted. Only takes effect * if the bounding box is known. * @param ctx A structure to store cascading state. * @param flags Which internal data should be recomputed. This can be any combination * of StateFlags. * @param reset State fields that should be reset before processing them. This is * a means to force a recomputation of internal data even if the item * considers it up to date. Mainly for internal use, such as * propagating bounding box recomputation to children when the item's * transform changes. */ void DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) { bool render_filters = _drawing.renderFilters(); bool outline = _drawing.outline(); // Set reset flags according to propagation status reset |= _propagate_state; _propagate_state = 0; _state &= ~reset; // reset state of this item if ((~_state & flags) == 0) return; // nothing to do // TODO this might be wrong if (_state & STATE_BBOX) { // we have up-to-date bbox if (!area.intersects(outline ? _bbox : _drawbox)) return; } // compute which elements need an update unsigned to_update = _state ^ flags; // this needs to be called before we recurse into children if (to_update & STATE_BACKGROUND) { _background_accumulate = _background_new; if (_child_type == CHILD_NORMAL && _parent->_background_accumulate) _background_accumulate = true; } UpdateContext child_ctx(ctx); if (_transform) { child_ctx.ctm = *_transform * ctx.ctm; } /* Remember the transformation matrix */ Geom::Affine ctm_change = _ctm.inverse() * child_ctx.ctm; _ctm = child_ctx.ctm; // update _bbox and call this function for children _state = _updateItem(area, child_ctx, flags, reset); if (to_update & STATE_BBOX) { // compute drawbox if (_filter && render_filters) { Geom::OptRect enlarged = _filter->filter_effect_area(_item_bbox); if (enlarged) { *enlarged *= ctm(); _drawbox = enlarged->roundOutwards(); } else { _drawbox = Geom::OptIntRect(); } } else { _drawbox = _bbox; } // Clipping if (_clip) { _clip->update(area, child_ctx, flags, reset); if (outline) { _bbox.unionWith(_clip->_bbox); } else { _drawbox.intersectWith(_clip->_bbox); } } // Masking if (_mask) { _mask->update(area, child_ctx, flags, reset); if (outline) { _bbox.unionWith(_mask->_bbox); } else { // for masking, we need full drawbox of mask _drawbox.intersectWith(_mask->_drawbox); } } } if (to_update & STATE_CACHE) { // Update cache score for this item if (_has_cache_iterator) { // remove old score information _drawing._candidate_items.erase(_cache_iterator); _has_cache_iterator = false; } double score = _cacheScore(); if (score >= _drawing._cache_score_threshold) { CacheRecord cr; cr.score = score; // if _cacheRect() is empty, a negative score will be returned from _cacheScore(), // so this will not execute (cache score threshold must be positive) cr.cache_size = _cacheRect()->area() * 4; cr.item = this; _drawing._candidate_items.push_front(cr); _cache_iterator = _drawing._candidate_items.begin(); _has_cache_iterator = true; } /* Update cache if enabled. * General note: here we only tell the cache how it has to transform * during the render phase. The transformation is deferred because * after the update the item can have its caching turned off, * e.g. because its filter was removed. This way we avoid tempoerarily * using more memory than the cache budget */ if (_cache) { Geom::OptIntRect cl = _cacheRect(); if (_visible && cl) { // never create cache for invisible items // this takes care of invalidation on transform _cache->scheduleTransform(*cl, ctm_change); } else { // Destroy cache for this item - outside of canvas or invisible. // The opposite transition (invisible -> visible or object // entering the canvas) is handled during the render phase delete _cache; _cache = NULL; } } } if (to_update & STATE_RENDER) { // now that we know drawbox, dirty the corresponding rect on canvas // unless filtered, groups do not need to render by themselves, only their members if (_fill_pattern) { _fill_pattern->update(area, child_ctx, flags, reset); } if (_stroke_pattern) { _stroke_pattern->update(area, child_ctx, flags, reset); } if (!is_drawing_group(this) || (_filter && render_filters)) { _markForRendering(); } } }