Пример #1
0
const CBoundingBoxAligned CModel::GetObjectSelectionBoundsRec()
{
	CBoundingBoxAligned objBounds = GetObjectBounds();		// updates the (children-not-included) object-space bounds if necessary

	// now extend these bounds to include the props' selection bounds (if any)
	for (size_t i = 0; i < m_Props.size(); ++i)
	{
		const Prop& prop = m_Props[i];
		if (prop.m_Hidden)
			continue; // prop is hidden from rendering, so it also shouldn't be used for selection

		CBoundingBoxAligned propSelectionBounds = prop.m_Model->GetObjectSelectionBoundsRec();
		if (propSelectionBounds.IsEmpty())
			continue;	// submodel does not wish to participate in selection box, exclude it

		// We have the prop's bounds in its own object-space; now we need to transform them so they can be properly added 
		// to the bounds in our object-space. For that, we need the transform of the prop attachment point.
		// 
		// We have the prop point information; however, it's not trivial to compute its exact location in our object-space
		// since it may or may not be attached to a bone (see SPropPoint), which in turn may or may not be in the middle of
		// an animation. The bone matrices might be of interest, but they're really only meant to be used for the animation 
		// system and are quite opaque to use from the outside (see @ref ValidatePosition).
		// 
		// However, a nice side effect of ValidatePosition is that it also computes the absolute world-space transform of 
		// our props and sets it on their respective models. In particular, @ref ValidatePosition will compute the prop's
		// world-space transform as either
		// 
		// T' = T x	B x O
		// or 
		// T' = T x O
		// 
		// where T' is the prop's world-space transform, T is our world-space transform, O is the prop's local
		// offset/rotation matrix, and B is an optional transformation matrix of the bone the prop is attached to 
		// (taking into account animation and everything).
		// 
		// From this, it is clear that either O or B x O is the object-space transformation matrix of the prop. So,
		// all we need to do is apply our own inverse world-transform T^(-1) to T' to get our desired result. Luckily,
		// this is precomputed upon setting the transform matrix (see @ref SetTransform), so it is free to fetch.
		
		CMatrix3D propObjectTransform = prop.m_Model->GetTransform(); // T'
		propObjectTransform.Concatenate(GetInvTransform()); // T^(-1) x T'

		// Transform the prop's bounds into our object coordinate space
		CBoundingBoxAligned transformedPropSelectionBounds;
		propSelectionBounds.Transform(propObjectTransform, transformedPropSelectionBounds);

		objBounds += transformedPropSelectionBounds;
	}

	return objBounds;
}
Пример #2
0
CodeGenFunction::EquivSet CodeGenFunction::EmitEquivalenceSet(const EquivalenceSet *S) {
  auto Result = EquivSets.find(S);
  if(Result != EquivSets.end())
    return Result->second;

  // Find the bounds of the set
  int64_t LowestBound = 0;
  int64_t HighestBound = 0;
  for(auto I : S->getObjects()) {
    auto Bounds  = GetObjectBounds(I.Var, I.E);
    LowestBound  = std::min(Bounds.first, LowestBound);
    HighestBound = std::max(Bounds.second, HighestBound);
    LocalVariablesInEquivSets.insert(std::make_pair(I.Var, Bounds.first));
  }
  EquivSet Set;
  // FIXME: more accurate alignment?
  Set.Ptr= Builder.Insert(new llvm::AllocaInst(CGM.Int8Ty,
                          llvm::ConstantInt::get(CGM.SizeTy, HighestBound - LowestBound),
                          CGM.getDataLayout().getTypeStoreSize(CGM.DoubleTy)),
                          "equivalence-set");
  Set.LowestBound = LowestBound;
  EquivSets.insert(std::make_pair(S, Set));
  return Set;
}