Exemplo n.º 1
0
	void LayoutEngine::addFloat(BoxPtr float_box)
	{
		ASSERT_LOG(!float_list_.empty(), "Empty float list.");
		if(float_box->getStyleNode()->getFloat() == Float::LEFT) {
			float_list_.top().left_.emplace_back(float_box);
		} else {
			float_list_.top().right_.emplace_back(float_box);
		}
	}
Exemplo n.º 2
0
void Border::createBorder(){ 
  INFO("Creating Border ...");

  glm::vec3 pos;
  BoxPtr obj;

  // Back & Front Wall
  for (int i = 0; i < NUMBLKX; i++) {
	for (int j = 0; j < NUMBLKY; j++) {
	  pos = glm::vec3(MINX + E_LEN/2 + i * E_LEN, 
					  MINY + E_LEN/2 + j * E_LEN, 
					  MAXZ - E_LEN/2);
	  obj = BoxPtr(new Box(pos, glm::vec3(0), 0));
	  obj->setup();
	  obj->setCollisionID(1);
	  CollisionManager::addCollisionObjectToGrid(obj);	 	  

	  pos = glm::vec3(MINX + E_LEN/2 + i * E_LEN, 
					  MINY + E_LEN/2 + j * E_LEN, 
					  MINZ + E_LEN/2);
	  obj = BoxPtr(new Box(pos, glm::vec3(0), 0));
	  obj->setup(); 
	  obj->setCollisionID(1);
	  CollisionManager::addCollisionObjectToGrid(obj);	  
	}
  }

  // Left & Right Wall
  for (int i = 1; i < NUMBLKZ - 1; i++) {
	for (int j = 0; j < NUMBLKY; j++) {
	  pos = glm::vec3(MINX + E_LEN/2, 
					  MINY + E_LEN/2 + j * E_LEN, 
					  MINZ + E_LEN/2 + i*E_LEN);
	  obj = BoxPtr(new Box(pos, glm::vec3(0), 0));
	  obj->setup(); 
	  obj->setCollisionID(1);
	  CollisionManager::addCollisionObjectToGrid(obj);
	  
	  pos = glm::vec3(MAXX - E_LEN/2, 
					  MINY + E_LEN/2 + j * E_LEN, 
					  MINZ + E_LEN/2 + i*E_LEN);
	  obj = BoxPtr(new Box(pos, glm::vec3(0), 0));
	  obj->setup(); 
	  obj->setCollisionID(1);
	  CollisionManager::addCollisionObjectToGrid(obj);
	  
	}
  }
}
Exemplo n.º 3
0
	TextBox::TextBox(const BoxPtr& parent, const StyleNodePtr& node, const RootBoxPtr& root)
		: Box(BoxId::TEXT, parent, node, root),
		  txt_(std::dynamic_pointer_cast<Text>(node->getNode())),
		  lines_(),
		  shadows_()
	{
		auto shadows = parent->getStyleNode()->getTextShadow();
		if(shadows) {
			// Process shadows in reverse order.
			for(auto it = shadows->getShadows().crbegin(); it != shadows->getShadows().crend(); ++it) {
				const css::TextShadow& shadow = *it;
				float xo = shadow.getOffset()[0].compute() / LayoutEngine::getFixedPointScaleFloat();
				float yo = shadow.getOffset()[1].compute() / LayoutEngine::getFixedPointScaleFloat();
				float br = shadow.getBlur().compute() / LayoutEngine::getFixedPointScaleFloat();
				KRE::ColorPtr color = shadow.getColor().compute();
				shadows_.emplace_back(xo, yo, br, color);
			}
		}
		txt_->transformText(getStyleNode(), true);
	}
Exemplo n.º 4
0
	void Box::addAbsoluteElement(LayoutEngine& eng, const Dimensions& containing, BoxPtr abs_box)
	{
		absolute_boxes_.emplace_back(abs_box);
		abs_box->layout(eng, containing);
	}
Exemplo n.º 5
0
	void InlineBlockBox::handlePostChildLayout(LayoutEngine& eng, BoxPtr child)
	{
		// Called after every child is laid out.
		setContentHeight(getHeight() + child->getHeight() + child->getMBPBottom());
	}
/**
* \brief Collision Partikel mit einer Box.
* \param box zu testende Box
*/
void ParticleSystem::collide(ParticlePtr part, BoxPtr box)
{ 
    //sphere in das lokale koordinatensystem der box bringen
	Vector3<float> particlePos = part->getPosition() - box->getRigidBody()->getPosition();
	Quaternion boxOri = box->getRigidBody()->getOrientation();
	const Quaternion& boxInvOri = boxOri.inverse();    
    particlePos = qRotate(particlePos, boxInvOri);
    
    //test auf collision mit den 6 seiten der box
    unsigned int cnt = 0;
	float rad = 3.0f;

	float right = dot(particlePos, Vector3<float>(1,0,0)) + rad;
	float left = dot(particlePos, Vector3<float>(-1,0,0)) - rad;
	float front = dot(particlePos, Vector3<float>(0,0,1)) + rad;
	float back = dot(particlePos, Vector3<float>(0,0,-1)) - rad;
	float top = dot(particlePos, Vector3<float>(0,1,0)) + rad;
	float bottom = dot(particlePos, Vector3<float>(0,-1,0)) - rad;
	
	
    float dR  = box->getWidth()/2 - right + rad;
    float dL  = box->getWidth()/2 - left + rad;
    float dF  = box->getDepth()/2 - front + rad;
    float dBa = box->getDepth()/2 - back + rad;
    float dT  = box->getHeight()/2 - top + rad; 
    float dBo = box->getHeight()/2 - bottom + rad; 
    
    if (right  >= 0 && dR >= 0)  
	{	
		cnt ++;
	    if (right >  box->getWidth()/2)
		  particlePos[X] = box->getWidth()/2;	
		else  		
		  particlePos[X] = right ;	
	}
	if (left   >  0 && dL >= 0)  
	{
		cnt ++;	
		if(left > box->getWidth()/2)
		  particlePos[X] = -box->getWidth()/2;
		else
		  particlePos[X] = -left ;
	}
	if (front  >= 0 && dF >= 0)  
	{
		cnt ++;
		if (front > box->getDepth()/2)  
		  particlePos[Z] = box->getDepth()/2;
		else
		  particlePos[Z] = front;	  
 	}
	if (back   >  0 && dBa >= 0)  
	{
		cnt ++;
		if (back > box->getDepth()/2)  
		  particlePos[Z] = -box->getDepth()/2;
		else
		  particlePos[Z] = -back;  	
 	}
	if (top    >= 0 && dT >= 0) 
	{
		cnt ++;
		if (top > box->getHeight()/2)  
		  particlePos[Y] = box->getHeight()/2;
		else
		  particlePos[Y] = top;	  
 	}
	if (bottom >  0 && dBo >= 0) 
	{
		cnt ++;
		if (bottom > box->getHeight()/2)  
		  particlePos[Y] = -box->getHeight()/2;
		else
		  particlePos[Y] = -bottom  ;
	}
    
	//test auf collision
    if (cnt >= 3)
	{
		
		//berechnung normalB und contactPoint
		const Vector3<float>& contactPoint 
			= qRotate(particlePos, boxOri) + box->getRigidBody()->getPosition();
		//cout << "C: " << contactPoint << endl;
		//cout << "P: " << part->getPosition() << endl;
		Vector3<float> normalB = part->getPosition() - contactPoint;
		//cout << normalB.length() <<"\n";

		//if (normalB.length() != 0)
		normalB.normalize();
		
		// folgender Abschnitt aus: 
		// CollisionSystem::collisionResponse(part, sphere, contactPoint, normalB);

		//berechnung der relativen geschwindigkeit in richtung normalB
		const Vector3<float>& velocityA = part->getVelocity();
		const Vector3<float>& velocityB = box->getRigidBody()->getVelocity();
		Vector3<float> velA = part->getVelocity();
		Vector3<float> forceA = part->getForce();


//		const Vector3<float>& rA = contactPoint - part->getPosition(); // vorher: particlePos!
//		const Vector3<float>& rB = contactPoint - box->getPosition();
		
		const Vector3<float>& vA = velocityA;
		const Vector3<float>& vB = velocityB;
		const Vector3<float>& vR = vA - vB;
		
		float vN = dot(vR, normalB);
		
//------------------Behandlung für colliding contact---------------------------------------
		if (vN <= 0.5)
		{	

//--------------------neue Behandlung aus Sphere kopiert-------------------------
			float vDoN = dot(velA, normalB);
			Vector3<float> vS = normalB * vDoN; 
		
			float fDoN = dot(forceA, normalB);
			Vector3<float> fS = normalB * fDoN;
			Vector3<float> force = part->getForce();
			force.normalize();
			if (dot (force, normalB) > 0 ){
				part->setVelocity(part->getVelocity() - vS);
				part->setVelocity(part->getVelocity() * 0.75);	// Wert: 0.75
				part->addForce((-1.0) * fS);
				part->setForce(part->getForce() * 0.75);	// Wert: 0.75
				part->setIsColliding(true);
			}
//------------------------------------------------------------------------------
			////berechnung der impuls-kraft in richtung normalB
			////float damping = (0.01f + box->getBounciness()) / 2.0f;
			//float damping = 0.12f;
			//float invMassA, invMassB = 0.0f;
			////Matrix<float> invTensorA(3,3);

			////Matrix<float> invTensorB = box->getInvWorldInertiaTensor();
		
			////test ob dynamisch
			//if(part->getIsDynamicFlag())
			//{	
			//	invMassA = part->getInvMass();
			//}
			//else 
			//	invMassA = 0.0;
			//
			//if(box->getRigidBody()->getIsDynamicFlag())
			//{	
			//	invMassB = box->getInvMass();
			//	//invTensorB = box->getRigidBody()->getInvWorldInertiaTensor();
			//}
			//else 
			//	invMassB = 0.0;
		
			//float fNum = -(/*1+*/damping)*(dot(normalB,(velocityA - velocityB)));
			//float fDenom = invMassA + invMassB;// + dot(crossA,uA)+dot(crossB,uB);

			//float impulseMagnitude = fNum / fDenom;

			//if (impulseMagnitude < 0){
			//Vector3<float> impulseForce = impulseMagnitude * normalB;

			///*impulseForce.normalize();
			//float vDoI = dot(velA, impulseForce);
			//float fDoI = dot(forceA, impulseForce);
			//Vec3 vS = impulseForce * vDoI;
			//Vec3 fS = impulseForce * fDoI;*/

			////part->setVelocity(part->getVelocity()[X], 0.0f, part->getVelocity()[Z]);
			////part->setVelocity(part->getVelocity() - vS);
			////part->addForce(fS);
			////setzen der linaren momente
			//if (part->getInvMass()!=0)
			//{
			//part->setVelocity(part->getVelocity() - impulseForce/invMassA);
			//part->setIsColliding(true);
			//}
			////part->setVelocity(part->getVelocity() + (impulseForce / invMassB));        
			//
			//}
		}
	}
	
}
Exemplo n.º 7
0
	void BlockBox::handlePostChildLayout(LayoutEngine& eng, BoxPtr child)
	{
		// Called after every child is laid out.
		//std::cerr << "t: " << (child->getTop()/65536.f) << ", h: " << (child->getHeight()/65536.f) << ", mbp-b: " << (child->getMBPBottom()/65536.f) << "\n";
		setContentHeight(child->getTop() + child->getHeight() + child->getMBPBottom());
	}
Exemplo n.º 8
0
	std::vector<BoxPtr> LayoutEngine::layoutChildren(const std::vector<StyleNodePtr>& children, BoxPtr parent)
	{
		StackManager<point> offset_manager(offset_, point(parent->getLeft(), parent->getTop()) + offset_.top());

		std::vector<BoxPtr> res;
		for(auto it = children.begin(); it != children.end(); ++it) {
			auto child = *it;
			auto node = child->getNode();
			ASSERT_LOG(node != nullptr, "Something went wrong, there was a StyleNode without an associated DOM node.");
			if(node->id() == NodeId::ELEMENT) {
				if(node->ignoreForLayout()) {
					continue;
				}
				// Adjust counters for list items as needed
				std::unique_ptr<StackManager<int>> li_manager;
				if(node->hasTag(ElementId::UL) || node->hasTag(ElementId::OL)) {
					li_manager.reset(new StackManager<int>(list_item_counter_, 0));
				}
				if(node->hasTag(ElementId::LI) ) {
					auto &top = list_item_counter_.top();
					++top;
				}

				const Display display = child->getDisplay();
				const Float cfloat = child->getFloat();
				const Position position = child->getPosition();

				if(display == Display::NONE) {
					// Do not create a box for this or it's children
					// early return
					continue;
				}

				if(position == Position::ABSOLUTE_POS) {
					// absolute positioned elements are taken out of the normal document flow
					parent->addAbsoluteElement(*this, parent->getDimensions(), std::make_shared<AbsoluteBox>(parent, child, root_));
				} else if(position == Position::FIXED) {
					// fixed positioned elements are taken out of the normal document flow
					root_->addFixed(std::make_shared<BlockBox>(parent, child, root_));
				} else {
					if(cfloat != Float::NONE) {
						// XXX need to add an offset to position for the float box based on body margin.
						// N.B. if the current display is one of the CssDisplay::TABLE* styles then this should be
						// a table box rather than a block box. Inline boxes are going to get wrapped in a BlockBox
						
						if(display == Display::BLOCK) {
							res.emplace_back(std::make_shared<BlockBox>(parent, child, root_));
						} else if(display == Display::LIST_ITEM) {
							res.emplace_back(std::make_shared<ListItemBox>(parent, child, root_, list_item_counter_.top()));
						} else if(display == Display::TABLE) {
							//root_->addFloatBox(*this, std::make_shared<TableBox>(parent, child), cfloat, offset_.top().x, offset_.top().y + (open_box != nullptr ? open_box->getCursor().y : 0));
							ASSERT_LOG(false, "Implement Table display");
						} else {
							// default to using a block box to wrap content.
							res.emplace_back(std::make_shared<BlockBox>(parent, child, root_));
						}
						continue;
					}
					switch(display) {
						case Display::NONE:
							// Do not create a box for this or it's children
							break;
						case Display::INLINE: {
							if(node->isReplaced()) {
								// replaced elements should generate a box.
								// XXX should these go into open_box?
								res.emplace_back(std::make_shared<InlineElementBox>(parent, child, root_));
							} else {
								// find first and last text children
								std::vector<StyleNodePtr>::const_iterator first_text_child = child->getChildren().end();
								std::vector<StyleNodePtr>::const_iterator last_text_child = child->getChildren().end();
								for(auto it = child->getChildren().begin(); it != child->getChildren().end(); ++it) {
									if(*it != nullptr && (*it)->getNode()->id() == NodeId::TEXT) {
										if(first_text_child == child->getChildren().end()) {
											first_text_child = it;
										}
										last_text_child = it;
									}
								}

								// non-replaced elements we just generate children and add them.
								for(auto it = child->getChildren().begin(); it != child->getChildren().end(); ++it) {
									auto& inline_child = *it;
									NodePtr inline_node = inline_child->getNode();
									if(inline_node != nullptr && inline_node->id() == NodeId::TEXT) {
										inline_child->inheritProperties(child);
									}
								}

								std::vector<BoxPtr> new_children = layoutChildren(child->getChildren(), parent);

								// alter border and padding to suit
								for(auto& box_child : new_children) {
									if(*first_text_child == box_child->getStyleNode()) {
										box_child->setFirstInlineChild();
									}
									if(*last_text_child == box_child->getStyleNode()) {
										box_child->setLastInlineChild();
									}
								}

								res.insert(res.end(), new_children.begin(), new_children.end());
							}
							break;
						}
						case Display::BLOCK: {
							res.emplace_back(std::make_shared<BlockBox>(parent, child, root_));
							break;
						}
						case Display::INLINE_BLOCK: {
							res.emplace_back(std::make_shared<InlineBlockBox>(parent, child, root_));
							break;
						}
						case Display::LIST_ITEM: {
							res.emplace_back(std::make_shared<ListItemBox>(parent, child, root_, list_item_counter_.top()));
							break;
						}
						case Display::TABLE:
						case Display::INLINE_TABLE:
						case Display::TABLE_ROW_GROUP:
						case Display::TABLE_HEADER_GROUP:
						case Display::TABLE_FOOTER_GROUP:
						case Display::TABLE_ROW:
						case Display::TABLE_COLUMN_GROUP:
						case Display::TABLE_COLUMN:
						case Display::TABLE_CELL:
						case Display::TABLE_CAPTION:
							ASSERT_LOG(false, "FIXME: LayoutEngine::formatNode(): " << display_string(display));
							break;
						default:
							ASSERT_LOG(false, "illegal display value: " << static_cast<int>(display));
							break;
					}
				}
			} else if(node->id() == NodeId::TEXT) {
				res.emplace_back(std::make_shared<TextBox>(parent, child, root_));
			} else {
				ASSERT_LOG(false, "Unhandled node id, only elements and text can be used in layout: " << static_cast<int>(node->id()));
			}
		}
		return res;
	}
Exemplo n.º 9
0
	void ListItemBox::handlePostChildLayout(LayoutEngine& eng, BoxPtr child) 
	{
		setContentHeight(getHeight() + child->getHeight() + child->getMBPBottom());
	}
Exemplo n.º 10
0
BoxPtr Box::create( Node *parent, const Set *childNodes )
{
	BoxPtr result = new Box;
	parent->addChild( result );

	// it's pretty natural to call this function passing childNodes == ScriptNode::selection().
	// unfortunately nodes will be removed from the selection as we reparent
	// them, so we have to make a copy of childNodes so our iteration isn't befuddled by
	// the changing contents. we can use this opportunity to weed out anything in childNodes
	// which isn't a direct child of parent though.
	StandardSetPtr verifiedChildNodes = new StandardSet();
	for( NodeIterator nodeIt( parent ); nodeIt != nodeIt.end(); nodeIt++ )
	{
		if( childNodes->contains( nodeIt->get() ) )
		{
			verifiedChildNodes->add( *nodeIt );
		}
	}

	// when a node we're putting in the box has connections to
	// a node remaining outside, we need to reroute the connection
	// via an intermediate plug on the box. this mapping maps input
	// plugs (be they internal or external) to intermediate input plugs.
	typedef std::pair<const Plug *, Plug *> PlugPair;
	typedef std::map<const Plug *, Plug *> PlugMap;
	PlugMap plugMap;

	for( size_t i = 0, e = verifiedChildNodes->size(); i < e; i++ )
	{
		Node *childNode = static_cast<Node *>( verifiedChildNodes->member( i ) );
		// reroute any connections to external nodes
		for( RecursivePlugIterator plugIt( childNode ); plugIt != plugIt.end(); plugIt++ )
		{
			Plug *plug = plugIt->get();
			if( plug->direction() == Plug::In )
			{
				Plug *input = plug->getInput<Plug>();
				if( input && !verifiedChildNodes->contains( input->node() ) )
				{
					PlugMap::const_iterator mapIt = plugMap.find( input );
					if( mapIt == plugMap.end() )
					{
						PlugPtr intermediateInput = plug->createCounterpart( result->promotedCounterpartName( plug ), Plug::In );
						// we want intermediate inputs to appear on the same side of the node as the
						// equivalent internal plug, so we copy the relevant metadata over.
						copyMetadata( plug, intermediateInput.get() );
						intermediateInput->setFlags( Plug::Dynamic, true );
						result->addChild( intermediateInput );
						intermediateInput->setInput( input );
						mapIt = plugMap.insert( PlugPair( input, intermediateInput.get() ) ).first;
					}
					plug->setInput( mapIt->second );
					plugIt.prune();
				}
			}
			else
			{
				// take a copy of the outputs, because we might be modifying the
				// original as we iterate.
				Plug::OutputContainer outputs = plug->outputs();
				if( !outputs.empty() )
				{
					typedef Plug::OutputContainer::const_iterator OutputIterator;
					for( OutputIterator oIt = outputs.begin(), eIt = outputs.end(); oIt != eIt; oIt++ )
					{
						Plug *output = *oIt;
						const Node *outputNode = output->node();
						if( outputNode->parent<Node>() == parent && !verifiedChildNodes->contains( outputNode ) )
						{
							PlugMap::const_iterator mapIt = plugMap.find( plug );
							if( mapIt == plugMap.end() )
							{
								PlugPtr intermediateOutput = plug->createCounterpart( result->promotedCounterpartName( plug ), Plug::Out );
								copyMetadata( plug, intermediateOutput.get() );
								intermediateOutput->setFlags( Plug::Dynamic, true );
								result->addChild( intermediateOutput );
								intermediateOutput->setInput( plug );
								mapIt = plugMap.insert( PlugPair( plug, intermediateOutput.get() ) ).first;
							}
							output->setInput( mapIt->second );
						}
					}
					plugIt.prune();
				}
			}
		}
		// reparent the child under the Box. it's important that we do this after adding the intermediate
		// input plugs, so that when they are serialised and reloaded, the inputs to the box are set before
		// the inputs to the nodes inside the box - see GafferSceneTest.ShaderAssignmentTest.testAssignShaderFromOutsideBox
		// for a test case highlighting this necessity.
		result->addChild( childNode );
	}

	return result;
}