Пример #1
1
	bool BsonDocument::InstantiateObject(DynamicObject::Table &t, DynamicObject &obj)
	{
		for(DynamicObject::Iterator it = t.begin();it != t.end();++it)
		{
			boost::shared_ptr<TypeInfoBase> member = obj.GetMember(it->first);
			if (member.get()==NULL)
				continue;
			if (member->IsArray())
			{
				boost::shared_ptr<ArrayBase> dest 	= boost::dynamic_pointer_cast<ArrayBase>(member);
				boost::shared_ptr<ArrayBase> source = boost::dynamic_pointer_cast<ArrayBase>(it->second);
				if (source.get()==NULL || dest.get()==NULL)
					continue;
				size_t count = source->Count();
				for(size_t i=0; i<count;++i)
				{
					boost::shared_ptr<TypeInfoBase> ps = (*source)[i];
					if (ps.get()==NULL) 	//invalid member 
						continue;
					if (ps->IsObject())
					{
						DynamicObject::Table &h = ps->GetObject<DynamicObject>()->GetTable();
						boost::shared_ptr<DynamicObject> o = ClassFactory::CreateObject(dest->ClassName);
						if (o.get() == NULL)
							continue;
						InstantiateObject(h, *o);
						boost::shared_ptr<TypeInfoBase> pBase(new TypeInfo<DynamicObject>(o));
						dest->Add(pBase);
					}
					else
					{
						dest->Add(ps);
					}
				}
				it->second.reset();
				continue;
			} 
			else if (member->IsObject())
			{
				boost::shared_ptr<TypeInfoBase> info = it->second;
				if (!info->IsObject())
					continue;
				
				DynamicObject::Table &h = info->GetObject<DynamicObject>()->GetTable();
				boost::shared_ptr<DynamicObject> o = member->GetObject<DynamicObject>();
				if (o.get() != NULL)
					InstantiateObject(h,*o);
				continue;
			}
			//else 
			
			boost::shared_ptr<TypeInfoBase> p = it->second;
			
			if (p->GetType()!=member->GetType())
			{
				if (p->GetType()==typeid(double) && member->GetType()==typeid(float))
				{
					boost::shared_ptr<double> d = p->GetObject<double>();
					boost::shared_ptr<float> f = member->GetObject<float>();
					*f=float(*d);
				}
				else if (p->GetType()==typeid(int64_t) && member->GetType()==typeid(uint64_t))
				{
					boost::shared_ptr<int64_t> d = p->GetObject<int64_t>();
					boost::shared_ptr<uint64_t> f = member->GetObject<uint64_t>();
					*f=uint64_t(*d);
				}
				else if (p->GetType()==typeid(int) && member->GetType()==typeid(uint32_t))
				{
					boost::shared_ptr<int> d = p->GetObject<int>();
					boost::shared_ptr<uint32_t> f = member->GetObject<uint32_t>();
					*f=uint32_t(*d);
				}
			}
			else
			{
				if (p->IsBinary())
				{
					boost::shared_ptr<TypeInfo<Binary> > binarySource = boost::dynamic_pointer_cast<TypeInfo<Binary> >(p);
					boost::shared_ptr<TypeInfo<Binary> > binaryDest = boost::dynamic_pointer_cast<TypeInfo<Binary> >(member);
					if (binarySource.get()!=NULL && binaryDest.get()!=NULL)
						*binaryDest->GetObject() = *binarySource->GetObject();
				}
				else if (p->GetType() == typeid(string))
				{
					boost::shared_ptr<string> strSource = p->GetObject<string>();
					boost::shared_ptr<string> strDest = member->GetObject<string>();
					if (strSource.get()!=NULL && strDest.get()!=NULL)
						*strDest = *strSource;
				}
				else
				{
					if (member->GetObject().get() !=NULL && p->GetObject().get() != NULL)
						memcpy(member->GetObject().get(), p->GetObject().get(), p->GetSize());
				}
			}
		}
		return true;
	}
Пример #2
0
void POVRayExport::exportParticle(std::ofstream& os, const shared_ptr<Particle>& p){
	const auto sphere=dynamic_cast<Sphere*>(p->shape.get());
	const auto capsule=dynamic_cast<Capsule*>(p->shape.get());
	const auto ellipsoid=dynamic_cast<Ellipsoid*>(p->shape.get());
	const auto wall=dynamic_cast<Wall*>(p->shape.get());
	const auto infCyl=dynamic_cast<InfCylinder*>(p->shape.get());
	const auto facet=dynamic_cast<Facet*>(p->shape.get());
	// convenience
	const auto& n0(p->shape->nodes[0]);


	if(sphere) os<<"sphere{ o, "<<sphere->radius<<" "<<makeTexture(p)<<" "<<node2pov(n0)<<" }";
	else if(capsule) os<<"sphere_sweep{ linear_spline, 2, <"<<-.5*capsule->shaft<<",0,0> ,"<<capsule->radius<<", <"<<.5*capsule->shaft<<",0,0> ,"<<capsule->radius<<" "<<makeTexture(p)<<" "<<node2pov(n0)<<" }";
	else if(ellipsoid) os<<"sphere{ o, 1 scale "<<vec2pov(ellipsoid->semiAxes)<<" "<<makeTexture(p)<<" "<<node2pov(n0)<<" }";
	else if(wall){
		if((wall->glAB.isEmpty())){ os<<"plane{ "<<Vector3r::Unit(wall->axis)<<", "<<wall->nodes[0]->pos[wall->axis]; }
		else{ // quad, as mesh2
			Vector3r a; a[wall->axis]=wall->nodes[0]->pos[wall->axis]; Vector3r b(a), c(a), d(a);
			short ax1((wall->axis+1)%3), ax2((wall->axis+2)%3);
			a[ax1]=wall->glAB.min()[0]; a[ax2]=wall->glAB.min()[1];
			b[ax1]=wall->glAB.min()[0]; b[ax2]=wall->glAB.max()[1];
			c[ax1]=wall->glAB.max()[0]; c[ax2]=wall->glAB.min()[1];
			d[ax1]=wall->glAB.max()[0]; d[ax2]=wall->glAB.max()[1];
			os<<"mesh2{ vertex_vectors { 4 "<<vec2pov(a)<<", "<<vec2pov(b)<<", "<<vec2pov(c)<<", "<<vec2pov(d)<<" } face_indices { 2, <0,2,1>, <1,2,3> }";
		}
		os<<makeTexture(p,wallTexture)<<" }"; // will use the default if wallTexture is empty
	}
	else if(infCyl){
		if(isnan(infCyl->glAB.maxCoeff())){ // infinite cylinder, use quadric for this
			Vector3r abc=Vector3r::Ones(); abc[infCyl->axis]=0;
			os<<"quadric{ "<<vec2pov(abc)<<", <0,0,0>, <0,0,0>, -1 "<<makeTexture(p)<<" "<<node2pov(n0)<<" }";
		} else {
			#if 0
			#endif
			// base point (global coords), first center
			Vector3r pBase(n0->pos); pBase[infCyl->axis]+=infCyl->glAB[0];
			// axis vector (global coords), pBase+pAxis is the second center
			Vector3r pAxis(Vector3r::Zero()); pAxis[infCyl->axis]=infCyl->glAB[1]-infCyl->glAB[0];
			// axial rotation; warn if not around the axis
			AngleAxisr aa(n0->ori); Vector3r axRotVecDeg(aa.axis()*aa.angle()*180./M_PI);
			if(aa.angle()>1e-6 && abs(aa.axis()[infCyl->axis])<.999999) LOG_WARN("#"<<p->id<<": InfCylinder rotation not aligned with its axis (cylinder axis "<<infCyl->axis<<"; rotation axis "<<aa.axis()<<", angle "<<aa.angle()<<")");
			bool open=!cylCapTexture.empty();
			if(open){
				os<<"/*capped cylinder*/";
				Vector3r normal=Vector3r::Unit(infCyl->axis);
				for(int i:{-1,1}){
					os<<"disc{ o, "<<vec2pov(i*normal)<<", "<<infCyl->radius<<" "<<makeTexture(p,cylCapTexture)<<" rotate "<<vec2pov(axRotVecDeg)<<" translate "<<vec2pov(i<0?pBase:(pBase+pAxis).eval());
					os<<" }";
				}
			}
			// length of the cylinder
			Real cylLen=(infCyl->glAB[1]-infCyl->glAB[0]);
			// non-axial rotation, from +x cyl to infCyl->axis (case-by-case)
			Vector3r nonAxRotVec=(infCyl->axis==0?Vector3r::Zero():(infCyl->axis==1?Vector3r(0,0,90):Vector3r(0,-90,0)));
			// cylinder spans +x*cylLen from origin, then rotated, so that the texture is rotated as well
			os<<"cylinder{ o, <"<<cylLen<<",0,0>, "<<infCyl->radius<<(open?" open ":" ")<<" "<<makeTexture(p)<<" rotate "<<vec2pov(nonAxRotVec)<<" rotate "<<vec2pov(axRotVecDeg)<<" translate "<<vec2pov(pBase)<<" }";
		}
	}
	else if(facet){
		// halfThick ignored for now, as well as connectivity
		if(facet->halfThick>0){
			Vector3r dp=facet->getNormal()*facet->halfThick;
			const Vector3r& a(facet->nodes[0]->pos); const Vector3r& b(facet->nodes[1]->pos); const Vector3r& c(facet->nodes[2]->pos);
			os<<"merge{ sphere_sweep{ linear_spline, 4 "<<vec2pov(a)<<", "<<facet->halfThick<<", "<<vec2pov(b)<<", "<<facet->halfThick<<", "<<vec2pov(c)<<", "<<facet->halfThick<<", "<<vec2pov(a)<<", "<<facet->halfThick<<" } triangle{"<<vec2pov(a+dp)<<", "<<vec2pov(b+dp)<<", "<<vec2pov(c+dp)<<" } triangle {"<<vec2pov(a-dp)<<", "<<vec2pov(b-dp)<<", "<<vec2pov(c-dp)<<" } "<<makeTexture(p)<<" }";
		} else {
			os<<"triangle{ "<<vec2pov(facet->nodes[0]->pos)<<", "<<vec2pov(facet->nodes[1]->pos)<<", "<<vec2pov(facet->nodes[2]->pos)<<" "<<makeTexture(p)<<" }";
		}
	}
	os<<" // id="<<p->id<<endl;
}
Пример #3
0
bool ezSurfaceResource::InteractWithSurface(ezWorld* pWorld, ezGameObjectHandle hObject, const ezVec3& vPosition,
                                            const ezVec3& vSurfaceNormal, const ezVec3& vIncomingDirection,
                                            const ezTempHashedString& sInteraction, const ezUInt16* pOverrideTeamID)
{
  const ezSurfaceInteraction* pIA = nullptr;
  if (!m_Interactions.TryGetValue(sInteraction.GetHash(), pIA))
  {
    // if this type of interaction is not defined on this surface, try to find it on the base surface

    if (m_Descriptor.m_hBaseSurface.IsValid())
    {
      ezResourceLock<ezSurfaceResource> pBase(m_Descriptor.m_hBaseSurface, ezResourceAcquireMode::NoFallback);
      return pBase->InteractWithSurface(pWorld, hObject, vPosition, vSurfaceNormal, vIncomingDirection, sInteraction, pOverrideTeamID);
    }

    return false;
  }

  // defined, but set to be empty
  if (!pIA->m_hPrefab.IsValid())
    return false;

  ezResourceLock<ezPrefabResource> pPrefab(pIA->m_hPrefab, ezResourceAcquireMode::NoFallback);

  ezVec3 vDir;

  switch (pIA->m_Alignment)
  {
    case ezSurfaceInteractionAlignment::SurfaceNormal:
      vDir = vSurfaceNormal;
      break;

    case ezSurfaceInteractionAlignment::IncidentDirection:
      vDir = -vIncomingDirection;
      ;
      break;

    case ezSurfaceInteractionAlignment::ReflectedDirection:
      vDir = vIncomingDirection.GetReflectedVector(vSurfaceNormal);
      break;

    case ezSurfaceInteractionAlignment::ReverseSurfaceNormal:
      vDir = -vSurfaceNormal;
      break;

    case ezSurfaceInteractionAlignment::ReverseIncidentDirection:
      vDir = vIncomingDirection;
      ;
      break;

    case ezSurfaceInteractionAlignment::ReverseReflectedDirection:
      vDir = -vIncomingDirection.GetReflectedVector(vSurfaceNormal);
      break;
  }

  vDir.Normalize();
  ezVec3 vTangent = vDir.GetOrthogonalVector().GetNormalized();

  // random rotation around the spawn direction
  {
    double randomAngle = pWorld->GetRandomNumberGenerator().DoubleInRange(0.0, ezMath::BasicType<double>::Pi() * 2.0);

    ezMat3 rotMat;
    rotMat.SetRotationMatrix(vDir, ezAngle::Radian((float)randomAngle));

    vTangent = rotMat * vTangent;
  }

  if (pIA->m_Deviation > ezAngle::Radian(0.0f))
  {
    ezAngle maxDeviation;

    /// \todo do random deviation, make sure to clamp max deviation angle
    switch (pIA->m_Alignment)
    {
      case ezSurfaceInteractionAlignment::IncidentDirection:
      case ezSurfaceInteractionAlignment::ReverseReflectedDirection:
      {
        const float fCosAngle = vDir.Dot(-vSurfaceNormal);
        const float fMaxDeviation = ezMath::BasicType<float>::Pi() - ezMath::ACos(fCosAngle).GetRadian();

        maxDeviation = ezMath::Min(pIA->m_Deviation, ezAngle::Radian(fMaxDeviation));
      }
      break;

      case ezSurfaceInteractionAlignment::ReflectedDirection:
      case ezSurfaceInteractionAlignment::ReverseIncidentDirection:
      {
        const float fCosAngle = vDir.Dot(vSurfaceNormal);
        const float fMaxDeviation = ezMath::BasicType<float>::Pi() - ezMath::ACos(fCosAngle).GetRadian();

        maxDeviation = ezMath::Min(pIA->m_Deviation, ezAngle::Radian(fMaxDeviation));
      }
      break;

      default:
        maxDeviation = pIA->m_Deviation;
        break;
    }

    const ezAngle deviation =
        ezAngle::Radian((float)pWorld->GetRandomNumberGenerator().DoubleMinMax(-maxDeviation.GetRadian(), maxDeviation.GetRadian()));

    // tilt around the tangent (we don't want to compute another random rotation here)
    ezMat3 matTilt;
    matTilt.SetRotationMatrix(vTangent, deviation);

    vDir = matTilt * vDir;
  }


  // finally compute the bi-tangent
  const ezVec3 vBiTangent = vDir.CrossRH(vTangent);

  ezMat3 mRot;
  mRot.SetColumn(0, vDir); // we always use X as the main axis, so align X with the direction
  mRot.SetColumn(1, vTangent);
  mRot.SetColumn(2, vBiTangent);

  ezTransform t;
  t.m_vPosition = vPosition;
  t.m_qRotation.SetFromMat3(mRot);
  t.m_vScale.Set(1.0f);

  // attach to dynamic objects
  ezGameObjectHandle hParent;

  ezGameObject* pObject = nullptr;
  if (pWorld->TryGetObject(hObject, pObject) && pObject->IsDynamic())
  {
    hParent = hObject;
    t.SetLocalTransform(pObject->GetGlobalTransform(), t);
  }

  ezHybridArray<ezGameObject*, 8> rootObjects;
  pPrefab->InstantiatePrefab(*pWorld, t, hParent, &rootObjects, pOverrideTeamID, nullptr);

  if (pObject != nullptr && pObject->IsDynamic())
  {
    ezMsgOnlyApplyToObject msg;
    msg.m_hObject = hParent;

    for (auto pRootObject : rootObjects)
    {
      pRootObject->PostMessageRecursive(msg, ezObjectMsgQueueType::AfterInitialized);
    }
  }

  return true;
}