Example #1
0
void ezPipeChannel_win::OnIOCompleted(IOContext* pContext, DWORD uiBytesTransfered, DWORD uiError)
{
  EZ_ASSERT_DEBUG(m_ThreadId == ezThreadUtils::GetCurrentThreadID(), "Function must be called from worker thread!");
  bool bRes = true;
  if (pContext == &m_InputState.Context)
  {
    if (!m_Connected)
    {
      if (!ProcessConnection())
        return;

      bool bHasOutput = false;
      {
        EZ_LOCK(m_OutputQueueMutex);
        bHasOutput = !m_OutputQueue.IsEmpty();
      }

      if (bHasOutput && m_OutputState.IsPending == 0)
        ProcessOutgoingMessages(0);
      if (m_InputState.IsPending)
        return;
    }
    bRes = ProcessIncomingMessages(uiBytesTransfered);
  }
  else
  {
    EZ_ASSERT_DEBUG(pContext == &m_OutputState.Context, "");
    bRes = ProcessOutgoingMessages(uiBytesTransfered);
  }
  if (!bRes && m_PipeHandle != INVALID_HANDLE_VALUE)
  {
    InternalDisconnect();
  }
}
Example #2
0
bool ezPipeChannel_win::ProcessOutgoingMessages(DWORD uiBytesWritten)
{
  EZ_ASSERT_DEBUG(m_Connected, "Must be connected to process outgoing messages.");
  EZ_ASSERT_DEBUG(m_ThreadId == ezThreadUtils::GetCurrentThreadID(), "Function must be called from worker thread!");

  if (m_OutputState.IsPending)
  {
    if (uiBytesWritten == 0)
    {
      // Don't reset isPending right away as we want to use it to decide
      // whether we need to wake up the worker thread again.
      ezLog::Error("pipe error: {0}", ezArgErrorCode(GetLastError()));
      m_OutputState.IsPending = false;
      return false;
    }

    EZ_LOCK(m_OutputQueueMutex);
    //message was send
    m_OutputQueue.PopFront();
  }

  if (m_PipeHandle == INVALID_HANDLE_VALUE)
  {
    m_OutputState.IsPending = false;
    return false;
  }
  const ezMemoryStreamStorage* storage = nullptr;
  {
    EZ_LOCK(m_OutputQueueMutex);
    if (m_OutputQueue.IsEmpty())
    {
      m_OutputState.IsPending = false;
      return true;
    }
    storage = &m_OutputQueue.PeekFront();
  }

  BOOL res = WriteFile(m_PipeHandle, storage->GetData(), storage->GetStorageSize(), &uiBytesWritten,
                       &m_OutputState.Context.Overlapped);

  if (!res)
  {
    ezUInt32 error = GetLastError();
    if (error == ERROR_IO_PENDING)
    {
      m_OutputState.IsPending = true;
      return true;
    }
    ezLog::Error("Write to pipe failed: {0}", ezArgErrorCode(error));
    return false;
  }

  m_OutputState.IsPending = true;
  return true;
}
Example #3
0
  VertexDataStream* Mesh::AddDataStream(ezGALVertexAttributeSemantic::Enum semantic, ezUInt32 uiNumElementsPerVertex,
                                        VertexElementType elementType)
  {
    // A few checks for meaningful element count.
    // These are necessary to keep the implementation of preprocessing functions like
    // MergeSubMeshesWithSameMaterials/ComputeNormals/ComputeTangents sane.
    switch (semantic)
    {
      case ezGALVertexAttributeSemantic::Position:
        EZ_ASSERT_DEBUG(uiNumElementsPerVertex == 3 && elementType == VertexElementType::FLOAT,
                        "Position vertex streams should always have exactly 3 float elements.");
        break;
      case ezGALVertexAttributeSemantic::Normal:
        EZ_ASSERT_DEBUG(uiNumElementsPerVertex == 3 && elementType == VertexElementType::FLOAT,
                        "Normal vertex streams should always have exactly 3 float elements.");
        break;
      case ezGALVertexAttributeSemantic::Tangent:
        EZ_ASSERT_DEBUG(uiNumElementsPerVertex == 3 && elementType == VertexElementType::FLOAT,
                        "Tangent vertex streams should always have exactly 3 float elements.");
        break;
      case ezGALVertexAttributeSemantic::BiTangent:
        EZ_ASSERT_DEBUG((uiNumElementsPerVertex == 3 || uiNumElementsPerVertex == 1) && elementType == VertexElementType::FLOAT,
                        "BiTangent vertex streams should have either 3 float elements (vector) or 1 float element (sign).");
        break;

      case ezGALVertexAttributeSemantic::BoneIndices0:
      case ezGALVertexAttributeSemantic::BoneIndices1:
      case ezGALVertexAttributeSemantic::BoneWeights0:
      case ezGALVertexAttributeSemantic::BoneWeights1:
        EZ_ASSERT_DEBUG(uiNumElementsPerVertex == 4 || uiNumElementsPerVertex == 1,
                        "Bone weights and index streams should have 1 or 4 elements (single bone / standard skinning).");
        break;
    }

    VertexDataStream* existingStream = nullptr;
    if (!m_VertexDataStreams.TryGetValue(static_cast<ezUInt32>(semantic), existingStream))
    {
      m_VertexDataStreams.Insert(semantic, EZ_DEFAULT_NEW(VertexDataStream, uiNumElementsPerVertex, m_Triangles.GetCount(), elementType));
      return m_VertexDataStreams[semantic];
    }
    else
    {
      if (uiNumElementsPerVertex != existingStream->GetNumElementsPerVertex() || elementType != existingStream->GetElementType())
      {
        return nullptr;
      }
      return existingStream;
    }
  }
Example #4
0
bool ezPipeChannel_win::ProcessConnection()
{
  EZ_ASSERT_DEBUG(m_ThreadId == ezThreadUtils::GetCurrentThreadID(), "Function must be called from worker thread!");
  if (m_InputState.IsPending)
    m_InputState.IsPending = false;

  BOOL res = ConnectNamedPipe(m_PipeHandle, &m_InputState.Context.Overlapped);
  if (res)
  {
    //EZ_REPORT_FAILURE
    return false;
  }

  ezUInt32 error = GetLastError();
  switch (error)
  {
    case ERROR_IO_PENDING:
      m_InputState.IsPending = true;
      break;
    case ERROR_PIPE_CONNECTED:
      m_Connected = true;
      break;
    case ERROR_NO_DATA:
      return false;
    default:
      ezLog::Error("Could not connect to pipe (Error code: {0})", ezArgErrorCode(error));
      return false;
  }

  return true;
}
Example #5
0
void ezPipeChannel_win::InternalDisconnect()
{
#if EZ_ENABLED(EZ_COMPILE_FOR_DEBUG)
  if (m_ThreadId != 0)
    EZ_ASSERT_DEBUG(m_ThreadId == ezThreadUtils::GetCurrentThreadID(), "Function must be called from worker thread!");
#endif
  if (m_InputState.IsPending || m_OutputState.IsPending)
  {
    CancelIo(m_PipeHandle);
  }

  if (m_PipeHandle != INVALID_HANDLE_VALUE)
  {
    CloseHandle(m_PipeHandle);
    m_PipeHandle = INVALID_HANDLE_VALUE;
  }

  while (m_InputState.IsPending || m_OutputState.IsPending)
  {
    FlushPendingOperations();
  }

  {
    EZ_LOCK(m_OutputQueueMutex);
    m_OutputQueue.Clear();
    m_Connected = false;
  }

  m_Events.Broadcast(ezIpcChannelEvent(m_Mode == Mode::Client ? ezIpcChannelEvent::DisconnectedFromServer : ezIpcChannelEvent::DisconnectedFromClient, this));
  // Raise in case another thread is waiting for new messages (as we would sleep forever otherwise).
  m_IncomingMessages.RaiseSignal();
}
Example #6
0
void ezQtPin::AddConnection(ezQtConnection* pConnection)
{
  EZ_ASSERT_DEBUG(!m_Connections.Contains(pConnection), "Connection already present!");
  m_Connections.PushBack(pConnection);

  ConnectedStateChanged(true);
  UpdateConnections();
}
Example #7
0
void ezQtPropertyWidget::PrepareToDie()
{
  EZ_ASSERT_DEBUG(!m_bUndead, "Object has already been marked for cleanup");

  m_bUndead = true;

  DoPrepareToDie();
}
Example #8
0
bool ezPipeChannel_win::ProcessIncomingMessages(DWORD uiBytesRead)
{
  EZ_ASSERT_DEBUG(m_ThreadId == ezThreadUtils::GetCurrentThreadID(), "Function must be called from worker thread!");
  if (m_InputState.IsPending)
  {
    m_InputState.IsPending = false;
    if (uiBytesRead == 0)
      return false;
  }

  while (true)
  {
    if (uiBytesRead == 0)
    {
      if (m_PipeHandle == INVALID_HANDLE_VALUE)
        return false;

      BOOL res = ReadFile(m_PipeHandle, m_InputBuffer, BUFFER_SIZE, &uiBytesRead,
                          &m_InputState.Context.Overlapped);

      if (!res)
      {
        ezUInt32 error = GetLastError();
        if (error == ERROR_IO_PENDING)
        {
          m_InputState.IsPending = true;
          return true;
        }
        if (m_Mode == Mode::Server)
        {
          // only log when in server mode, otherwise this can result in an endless recursion
          ezLog::Error("Read from pipe failed: {0}", ezArgErrorCode(error));
        }
        return false;
      }
      m_InputState.IsPending = true;
      return true;
    }

    EZ_ASSERT_DEBUG(uiBytesRead != 0, "We really should have data at this point.");
    ReceiveMessageData(ezArrayPtr<ezUInt8>(m_InputBuffer, uiBytesRead));
    uiBytesRead = 0;
  }
  return true;
}
Example #9
0
  ezStatus Importer::ImportSkeleton(ezEditableSkeleton& out_Skeleton, const ezSharedPtr<Scene>& scene)
  {
    const float fScale = 1.0f;
    const ezMat3 mTransformation = ezMat3::IdentityMatrix();
    const ezMat3 mTransformRotations = ezMat3::IdentityMatrix();

    const ezUInt32 numJoints = scene->m_Skeleton.GetJointCount();

    ezDynamicArray<ezEditableSkeletonJoint*> allJoints;
    allJoints.SetCountUninitialized(numJoints);

    ezSet<ezString> jointNames;
    ezStringBuilder tmp;

    for (ezUInt32 b = 0; b < numJoints; ++b)
    {
      const ezTransform mJointTransform = scene->m_Skeleton.GetJointByIndex(b).GetBindPoseLocalTransform();

      allJoints[b] = EZ_DEFAULT_NEW(ezEditableSkeletonJoint);
      allJoints[b]->m_sName = scene->m_Skeleton.GetJointByIndex(b).GetName();
      allJoints[b]->m_Transform = mJointTransform;
      allJoints[b]->m_Transform.m_vScale.Set(1.0f);

      allJoints[b]->m_fLength = 0.1f;
      allJoints[b]->m_fThickness = 0.01f;
      allJoints[b]->m_fWidth = 0.01f;
      allJoints[b]->m_Geometry = ezSkeletonJointGeometryType::None;

      if (jointNames.Contains(allJoints[b]->m_sName))
      {
        tmp = allJoints[b]->m_sName.GetData();
        tmp.AppendFormat("_joint{0}", b);
        allJoints[b]->m_sName.Assign(tmp.GetData());
      }

      jointNames.Insert(allJoints[b]->m_sName.GetString());

      if (scene->m_Skeleton.GetJointByIndex(b).IsRootJoint())
      {
        allJoints[b]->m_Transform.m_vPosition = mTransformation * allJoints[b]->m_Transform.m_vPosition;
        allJoints[b]->m_Transform.m_qRotation.SetFromMat3(mTransformRotations * allJoints[b]->m_Transform.m_qRotation.GetAsMat3());

        out_Skeleton.m_Children.PushBack(allJoints[b]);
      }
      else
      {
        allJoints[b]->m_Transform.m_vPosition = fScale * allJoints[b]->m_Transform.m_vPosition;

        ezUInt32 parentIdx = scene->m_Skeleton.GetJointByIndex(b).GetParentIndex();
        EZ_ASSERT_DEBUG(parentIdx < b, "Invalid parent joint index");
        allJoints[parentIdx]->m_Children.PushBack(allJoints[b]);
      }
    }

    return ezStatus(EZ_SUCCESS);
  }
Example #10
0
void ezQtPin::RemoveConnection(ezQtConnection* pConnection)
{
  EZ_ASSERT_DEBUG(m_Connections.Contains(pConnection), "Connection not present!");
  m_Connections.RemoveAndSwap(pConnection);

  if (m_Connections.IsEmpty())
    ConnectedStateChanged(false);

  UpdateConnections();
}
Example #11
0
void ezTypelessResourceHandle::operator=(const ezTypelessResourceHandle& rhs)
{
  EZ_ASSERT_DEBUG(this != &rhs, "Cannot assign a resource handle to itself! This would invalidate the handle.");

  Invalidate();

  m_pResource = rhs.m_pResource;

  if (m_pResource)
    IncreaseResourceRefCount(reinterpret_cast<ezResource*>(m_pResource));
}
Example #12
0
void ezPipeChannel_win::AddToMessageLoop(ezMessageLoop* pMsgLoop)
{
  if (m_PipeHandle != INVALID_HANDLE_VALUE)
  {
    ezMessageLoop_win* pMsgLoopWin = static_cast<ezMessageLoop_win*>(pMsgLoop);

    ULONG_PTR key = reinterpret_cast<ULONG_PTR>(this);
    HANDLE port = CreateIoCompletionPort(m_PipeHandle, pMsgLoopWin->GetPort(), key, 1);
    EZ_ASSERT_DEBUG(pMsgLoopWin->GetPort() == port, "Failed to CreateIoCompletionPort: {0}", ezArgErrorCode(GetLastError()));
  }
}
Example #13
0
void ezSceneViewContext::PickObjectAt(ezUInt16 x, ezUInt16 y)
{
  // remote processes do not support picking, just ignore this
  if (ezEditorEngineProcessApp::GetSingleton()->IsRemoteMode())
    return;

  ezViewPickingResultMsgToEditor res;

  ezView* pView = nullptr;
  if (ezRenderWorld::TryGetView(m_hView, pView) && pView->IsRenderPassReadBackPropertyExisting("EditorPickingPass", "PickingMatrix"))
  {
    pView->SetRenderPassProperty("EditorPickingPass", "PickingPosition", ezVec2(x, y));
    ezVariant varMat = pView->GetRenderPassReadBackProperty("EditorPickingPass", "PickingMatrix");

    if (varMat.IsA<ezMat4>())
    {
      const ezUInt32 uiPickingID = pView->GetRenderPassReadBackProperty("EditorPickingPass", "PickingID").ConvertTo<ezUInt32>();
      // const float fPickingDepth = pView->GetRenderPassReadBackProperty("EditorPickingPass", "PickingDepth").ConvertTo<float>();
      res.m_vPickedNormal = pView->GetRenderPassReadBackProperty("EditorPickingPass", "PickingNormal").ConvertTo<ezVec3>();
      res.m_vPickingRayStartPosition =
          pView->GetRenderPassReadBackProperty("EditorPickingPass", "PickingRayStartPosition").ConvertTo<ezVec3>();
      res.m_vPickedPosition = pView->GetRenderPassReadBackProperty("EditorPickingPass", "PickingPosition").ConvertTo<ezVec3>();

      EZ_ASSERT_DEBUG(!res.m_vPickedPosition.IsNaN(), "");

      const ezUInt32 uiComponentID = (uiPickingID & 0x00FFFFFF);
      const ezUInt32 uiPartIndex = (uiPickingID >> 24) & 0x7F; // highest bit indicates whether the object is dynamic, ignore this

      res.m_ComponentGuid = GetDocumentContext()->m_Context.m_ComponentPickingMap.GetGuid(uiComponentID);
      res.m_OtherGuid = GetDocumentContext()->m_Context.m_OtherPickingMap.GetGuid(uiComponentID);

      if (res.m_ComponentGuid.IsValid())
      {
        ezComponentHandle hComponent = GetDocumentContext()->m_Context.m_ComponentMap.GetHandle(res.m_ComponentGuid);

        ezEngineProcessDocumentContext* pDocumentContext = GetDocumentContext();

        // check whether the component is still valid
        ezComponent* pComponent = nullptr;
        if (pDocumentContext->GetWorld()->TryGetComponent<ezComponent>(hComponent, pComponent))
        {
          // if yes, fill out the parent game object guid
          res.m_ObjectGuid = GetDocumentContext()->m_Context.m_GameObjectMap.GetGuid(pComponent->GetOwner()->GetHandle());
          res.m_uiPartIndex = uiPartIndex;
        }
        else
        {
          res.m_ComponentGuid = ezUuid();
        }
      }
    }
  }
Example #14
0
void ezQtPropertyWidget::Init(ezQtPropertyGridWidget* pGrid, ezObjectAccessorBase* pObjectAccessor, const ezRTTI* pType,
                              const ezAbstractProperty* pProp)
{
  m_pGrid = pGrid;
  m_pObjectAccessor = pObjectAccessor;
  m_pType = pType;
  m_pProp = pProp;
  EZ_ASSERT_DEBUG(m_pGrid && m_pObjectAccessor && m_pType && m_pProp, "");

  if (pProp->GetAttributeByType<ezReadOnlyAttribute>() != nullptr || pProp->GetFlags().IsSet(ezPropertyFlags::ReadOnly))
    setEnabled(false);

  OnInit();
}
Example #15
0
void ezSphereVisualizerAdapter::Update()
{
  m_Gizmo.SetVisible(m_bVisualizerIsVisible);
  ezObjectAccessorBase* pObjectAccessor = GetObjectAccessor();
  const ezSphereVisualizerAttribute* pAttr = static_cast<const ezSphereVisualizerAttribute*>(m_pVisualizerAttr);

  m_Scale = 1.0f;

  if (!pAttr->GetRadiusProperty().IsEmpty())
  {
    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetRadiusProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<float>(), "Invalid property bound to ezSphereVisualizerAttribute 'radius'");
    m_Scale = value.ConvertTo<float>();
  }

  if (!pAttr->GetColorProperty().IsEmpty())
  {
    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetColorProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<ezColor>(), "Invalid property bound to ezSphereVisualizerAttribute 'color'");
    m_Gizmo.SetColor(value.ConvertTo<ezColor>());
  }

  m_vPositionOffset = pAttr->m_vOffset;

  if (!pAttr->GetOffsetProperty().IsEmpty())
  {
    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetOffsetProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<ezVec3>(), "Invalid property bound to ezSphereVisualizerAttribute 'offset'");
    m_vPositionOffset += value.ConvertTo<ezVec3>();
  }
}
Example #16
0
void ezSimdQuat::SetSlerp(const ezSimdQuat& qFrom, const ezSimdQuat& qTo, const ezSimdFloat& t)
{
  EZ_ASSERT_DEBUG((t >= 0.0f) && (t <= 1.0f), "Invalid lerp factor.");

  const ezSimdFloat one = 1.0f;
  const ezSimdFloat qdelta = 1.0f - 0.001f;

  const ezSimdFloat fDot = qFrom.m_v.Dot<4>(qTo.m_v);

  ezSimdFloat cosTheta = fDot;

  bool bFlipSign = false;
  if (cosTheta < 0.0f)
  {
    bFlipSign = true;
    cosTheta = -cosTheta;
  }

  ezSimdFloat t0, t1;

  if (cosTheta < qdelta)
  {
    ezAngle theta = ezMath::ACos(cosTheta);

    // use sqrtInv(1+c^2) instead of 1.0/sin(theta)
    const ezSimdFloat iSinTheta = (one - (cosTheta * cosTheta)).GetInvSqrt();
    const ezAngle tTheta = (float)t * theta;

    ezSimdFloat s0 = ezMath::Sin(theta - tTheta);
    ezSimdFloat s1 = ezMath::Sin(tTheta);

    t0 = s0 * iSinTheta;
    t1 = s1 * iSinTheta;
  }
  else
  {
    // If q0 is nearly the same as q1 we just linearly interpolate
    t0 = one - t;
    t1 = t;
  }

  if (bFlipSign)
    t1 = -t1;

  m_v = qFrom.m_v * t0 + qTo.m_v * t1;

  Normalize();
}
Example #17
0
void ezGameObjectGizmoEditTool::SelectionManagerEventHandler(const ezSelectionManagerEvent& e)
{
  switch (e.m_Type)
  {
    case ezSelectionManagerEvent::Type::SelectionCleared:
      m_GizmoSelection.Clear();
      UpdateGizmoVisibleState();
      break;

    case ezSelectionManagerEvent::Type::SelectionSet:
    case ezSelectionManagerEvent::Type::ObjectAdded:
      EZ_ASSERT_DEBUG(m_GizmoSelection.IsEmpty(), "This array should have been cleared when the gizmo lost focus");
      UpdateGizmoVisibleState();
      break;
  }
}
Example #18
0
void ezDirectionVisualizerAdapter::Update()
{
  m_Gizmo.SetVisible(m_bVisualizerIsVisible);
  const ezDirectionVisualizerAttribute* pAttr = static_cast<const ezDirectionVisualizerAttribute*>(m_pVisualizerAttr);

  if (!pAttr->GetColorProperty().IsEmpty())
  {
    ezObjectAccessorBase* pObjectAccessor = GetObjectAccessor();

    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetColorProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<ezColor>(), "Invalid property bound to ezDirectionVisualizerAttribute 'color'");
    m_Gizmo.SetColor(value.ConvertTo<ezColor>());
  }
}
Example #19
0
bool ezRTTI::DispatchMessage(const void* pInstance, ezMessage& msg) const
{
  EZ_ASSERT_DEBUG(m_bGatheredDynamicMessageHandlers, "Message handler table should have been gathered at this point");

  const ezUInt32 uiIndex = msg.GetId() - m_uiMsgIdOffset;

  // m_DynamicMessageHandlers contains all message handlers of this type and all base types
  if (uiIndex < m_DynamicMessageHandlers.GetCount())
  {
    ezAbstractMessageHandler* pHandler = m_DynamicMessageHandlers[uiIndex];
    if (pHandler != nullptr && pHandler->IsConst())
    {
      (*pHandler)(pInstance, msg);
      return true;
    }
  }

  return false;
}
Example #20
0
ezQtTypeWidget::ezQtTypeWidget(QWidget* pParent, ezQtPropertyGridWidget* pGrid, ezObjectAccessorBase* pObjectAccessor, const ezRTTI* pType,
                               const char* szIncludeProperties, const char* szExcludeProperties)
    : QWidget(pParent)
    , m_pGrid(pGrid)
    , m_pObjectAccessor(pObjectAccessor)
    , m_pType(pType)
{
  EZ_ASSERT_DEBUG(m_pGrid && m_pObjectAccessor && m_pType, "");
  m_pLayout = new QGridLayout(this);
  m_pLayout->setColumnStretch(0, 1);
  m_pLayout->setColumnStretch(1, 0);
  m_pLayout->setColumnMinimumWidth(1, 5);
  m_pLayout->setColumnStretch(2, 2);
  m_pLayout->setMargin(0);
  m_pLayout->setSpacing(0);
  setLayout(m_pLayout);

  m_pGrid->GetObjectManager()->m_PropertyEvents.AddEventHandler(ezMakeDelegate(&ezQtTypeWidget::PropertyEventHandler, this));
  m_pGrid->GetCommandHistory()->m_Events.AddEventHandler(ezMakeDelegate(&ezQtTypeWidget::CommandHistoryEventHandler, this));
  ezManipulatorManager::GetSingleton()->m_Events.AddEventHandler(ezMakeDelegate(&ezQtTypeWidget::ManipulatorManagerEventHandler, this));

  BuildUI(pType, szIncludeProperties, szExcludeProperties);
}
Example #21
0
void ezWorld::PatchHierarchyData(ezGameObject* pObject, ezGameObject::TransformPreservation preserve)
{
  ezGameObject* pParent = pObject->GetParent();

  RecreateHierarchyData(pObject, pObject->IsDynamic());

  pObject->m_pTransformationData->m_pParentData = pParent != nullptr ? pParent->m_pTransformationData : nullptr;

  if (preserve == ezGameObject::TransformPreservation::PreserveGlobal)
  {
    pObject->SetGlobalTransform(pObject->m_pTransformationData->m_globalTransform);
  }
  else
  {
    pObject->UpdateGlobalTransform();
  }

  for (auto it = pObject->GetChildren(); it.IsValid(); ++it)
  {
    PatchHierarchyData(it, preserve);
  }
  EZ_ASSERT_DEBUG(pObject->m_pTransformationData != pObject->m_pTransformationData->m_pParentData, "Hierarchy corrupted!");
}
Example #22
0
  void ValidateSceneGraph(Scene* scene)
  {
    if (!scene)
      return;

    ezHashSet<const Node*> visitedNodes;
    ezDynamicArray<const Node*> queue;

    for (const HierarchyObject* object : scene->GetRootObjects())
    {
      // EZ_ASSERT_DEBUG(!object->GetParent().IsValid(), "Root object has a parent!");

      const Node* currentNode = object->Cast<Node>();
      if (currentNode)
      {
        visitedNodes.Clear();
        queue.Clear();
        queue.PushBack(currentNode);

        while (!queue.IsEmpty())
        {
          currentNode = queue.PeekBack();
          queue.PopBack();
          EZ_ASSERT_DEBUG(visitedNodes.Insert(currentNode) == false, "Imported scene contains cycles in its graph.");

          for (ObjectHandle child : currentNode->m_Children)
          {
            // EZ_ASSERT_DEBUG(scene->GetObject(object->GetParent()) == currentNode, "Child's parent pointer is incorrect!");

            const Node* childNode = object->Cast<Node>();
            if (childNode)
              queue.PushBack(childNode);
          }
        }
      }
    }
  }
Example #23
0
void ezWorld::LinkToParent(ezGameObject* pObject)
{
  EZ_ASSERT_DEBUG(pObject->m_NextSiblingIndex == 0 && pObject->m_PrevSiblingIndex == 0,
                  "Object is either still linked to another parent or data was not cleared.");
  if (ezGameObject* pParentObject = pObject->GetParent())
  {
    const ezUInt32 uiIndex = pObject->m_InternalId.m_InstanceIndex;

    if (pParentObject->m_FirstChildIndex != 0)
    {
      pObject->m_PrevSiblingIndex = pParentObject->m_LastChildIndex;
      GetObjectUnchecked(pParentObject->m_LastChildIndex)->m_NextSiblingIndex = uiIndex;
    }
    else
    {
      pParentObject->m_FirstChildIndex = uiIndex;
    }

    pParentObject->m_LastChildIndex = uiIndex;
    pParentObject->m_ChildCount++;

    pObject->m_pTransformationData->m_pParentData = pParentObject->m_pTransformationData;
  }
}
Example #24
0
void ezDirectionVisualizerAdapter::UpdateGizmoTransform()
{
  const ezDirectionVisualizerAttribute* pAttr = static_cast<const ezDirectionVisualizerAttribute*>(m_pVisualizerAttr);
  float fScale = pAttr->m_fScale;

  if (!pAttr->GetLengthProperty().IsEmpty())
  {
    ezObjectAccessorBase* pObjectAccessor = GetObjectAccessor();

    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetLengthProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<float>(), "Invalid property bound to ezDirectionVisualizerAttribute 'length'");
    fScale *= value.ConvertTo<float>();
  }

  const ezQuat axisRotation = GetBasisRotation(ezBasisAxis::PositiveX, pAttr->m_Axis);

  ezTransform t;
  t.m_qRotation = axisRotation;
  t.m_vScale = ezVec3(fScale);
  t.m_vPosition = axisRotation * ezVec3(fScale, 0, 0);
  m_Gizmo.SetTransformation(GetObjectTransform() * t);
}
Example #25
0
  void Mesh::AddData(const Mesh& mesh, const ezTransform& transform)
  {
    ezMat4 transformMat = transform.GetAsMat4();
    ezMat4 normalTransformMat = transformMat.GetInverse(0.0f).GetTranspose();

    // Create new triangles.
    ezUInt32 oldTriangleCount = GetNumTriangles();
    AddTriangles(mesh.GetNumTriangles());

    ezArrayPtr<const Mesh::Triangle> sourceTriangles = mesh.GetTriangles();
    ezArrayPtr<const Mesh::Triangle> targetTriangles = GetTriangles().GetSubArray(oldTriangleCount);
    EZ_ASSERT_DEBUG(sourceTriangles.GetCount() == targetTriangles.GetCount(), "Something is wrong with triangle allocation!");

    for (auto it = mesh.m_VertexDataStreams.GetIterator(); it.IsValid(); ++it)
    {
      const VertexDataStream* sourceStream = it.Value();
      VertexDataStream* targetStream = AddDataStream(static_cast<ezGALVertexAttributeSemantic::Enum>(it.Key()),
                                                     sourceStream->GetNumElementsPerVertex(), sourceStream->GetElementType());
      if (!targetStream)
      {
        ezLog::SeriousWarning("Cannot merge mesh {0} properly since it has a vertex data stream with semantic {1} that uses {2} elements "
                              "instead of 'unkown' which is used by the merge target. Skipping this data stream.",
                              mesh.m_Name, it.Key(), sourceStream->GetNumElementsPerVertex());
        continue;
      }

      // Copy data.
      ezUInt32 targetBaseDataIndex = targetStream->m_Data.GetCount();
      targetStream->m_Data.PushBackRange(sourceStream->m_Data);

      // Transform data.
      if (!transform.IsIdentical(ezTransform::IdentityTransform()))
      {
        const ezUInt32 attributeSize = targetStream->GetAttributeSize();

        // Positions
        if (it.Key() == ezGALVertexAttributeSemantic::Position)
        {
          for (ezUInt32 i = targetBaseDataIndex; i < targetStream->m_Data.GetCount(); i += attributeSize)
          {
            ezVec3& pos = *reinterpret_cast<ezVec3*>(&targetStream->m_Data[i]);
            pos = transformMat.TransformPosition(pos);
          }
        }
        // Directions
        else if (it.Key() == ezGALVertexAttributeSemantic::Normal || it.Key() == ezGALVertexAttributeSemantic::Tangent ||
                 it.Key() == ezGALVertexAttributeSemantic::BiTangent)
        {
          for (ezUInt32 i = targetBaseDataIndex; i < targetStream->m_Data.GetCount(); i += attributeSize)
          {
            ezVec3& dir = *reinterpret_cast<ezVec3*>(&targetStream->m_Data[i]);
            dir = normalTransformMat.TransformDirection(dir);
          }
        }
      }

      // Set mapping
      for (ezUInt32 tri = 0; tri < sourceTriangles.GetCount(); ++tri)
      {
        for (int v = 0; v < 3; ++v)
        {
          VertexDataIndex sourceDataIndex = sourceStream->GetDataIndex(sourceTriangles[tri].m_Vertices[v]);
          if (sourceDataIndex.IsValid())
            targetStream->SetDataIndex(targetTriangles[tri].m_Vertices[v], targetBaseDataIndex + sourceDataIndex.GetValue());
        }
      }
    }

    // Add submeshes.
    ezUInt32 oldSubMeshCount = m_SubMeshes.GetCount();
    m_SubMeshes.PushBackRange(mesh.m_SubMeshes);
    for (ezUInt32 i = oldSubMeshCount; i < m_SubMeshes.GetCount(); ++i)
    {
      m_SubMeshes[i].m_uiFirstTriangle += oldTriangleCount;
    }

    // Add skeleton if existent
    // TODO: What if multiple, incompatible skeletons are found(?)
    // For now: Remove skeleton and import unskinned
    // if (mesh.m_pSkeleton)
    //{
    //  if (m_pSkeleton)
    //  {
    //    if (!m_pSkeleton->IsCompatibleWith(mesh.m_pSkeleton.Borrow()))
    //    {
    //      ezLog::Warning("Found incompatible skeletons during mesh merging in mesh '{0}', import will be without skeletons!",
    //      m_Name.GetData()); m_pSkeleton.Reset();
    //    }
    //  }
    //  else
    //  {
    //    m_pSkeleton = EZ_DEFAULT_NEW(ezSkeleton, *mesh.m_pSkeleton);
    //  }
    //}
  }
Example #26
0
void ezRTTI::SanityCheckType(ezRTTI* pType)
{
  EZ_ASSERT_DEV(pType->GetTypeFlags().IsSet(ezTypeFlags::StandardType) + pType->GetTypeFlags().IsSet(ezTypeFlags::IsEnum) +
                        pType->GetTypeFlags().IsSet(ezTypeFlags::Bitflags) + pType->GetTypeFlags().IsSet(ezTypeFlags::Class) ==
                    1,
                "Types are mutually exclusive!");

  for (auto pProp : pType->m_Properties)
  {
    const ezRTTI* pSpecificType = pProp->GetSpecificType();

    EZ_ASSERT_DEBUG(IsValidIdentifierName(pProp->GetPropertyName()), "Property name is invalid: '{0}'", pProp->GetPropertyName());

    // if (!IsValidIdentifierName(pProp->GetPropertyName()))
    //{
    //  ezStringBuilder s;
    //  s.Format("RTTI: {0}\n", pProp->GetPropertyName());

    //  OutputDebugStringA(s.GetData());
    //}

    if (pProp->GetCategory() != ezPropertyCategory::Function)
    {
      EZ_ASSERT_DEV(pProp->GetFlags().IsSet(ezPropertyFlags::StandardType) + pProp->GetFlags().IsSet(ezPropertyFlags::IsEnum) +
                            pProp->GetFlags().IsSet(ezPropertyFlags::Bitflags) + pProp->GetFlags().IsSet(ezPropertyFlags::Class) <=
                        1,
                    "Types are mutually exclusive!");
    }

    switch (pProp->GetCategory())
    {
      case ezPropertyCategory::Constant:
      {
        EZ_ASSERT_DEV(pSpecificType->GetTypeFlags().IsSet(ezTypeFlags::StandardType), "Only standard type constants are supported!");
      }
      break;
      case ezPropertyCategory::Member:
      {
        EZ_ASSERT_DEV(pProp->GetFlags().IsSet(ezPropertyFlags::StandardType) ==
                          pSpecificType->GetTypeFlags().IsSet(ezTypeFlags::StandardType),
                      "Property-Type missmatch!");
        EZ_ASSERT_DEV(pProp->GetFlags().IsSet(ezPropertyFlags::IsEnum) == pSpecificType->GetTypeFlags().IsSet(ezTypeFlags::IsEnum),
                      "Property-Type missmatch! Use EZ_BEGIN_STATIC_REFLECTED_ENUM for type and EZ_ENUM_MEMBER_PROPERTY / "
                      "EZ_ENUM_ACCESSOR_PROPERTY for property.");
        EZ_ASSERT_DEV(pProp->GetFlags().IsSet(ezPropertyFlags::Bitflags) == pSpecificType->GetTypeFlags().IsSet(ezTypeFlags::Bitflags),
                      "Property-Type missmatch! Use EZ_BEGIN_STATIC_REFLECTED_ENUM for type and EZ_BITFLAGS_MEMBER_PROPERTY / "
                      "EZ_BITFLAGS_ACCESSOR_PROPERTY for property.");
        EZ_ASSERT_DEV(pProp->GetFlags().IsSet(ezPropertyFlags::Class) == pSpecificType->GetTypeFlags().IsSet(ezTypeFlags::Class),
                      "If ezPropertyFlags::Class is set, the property type must be ezTypeFlags::Class and vise versa.");
      }
      break;
      case ezPropertyCategory::Array:
      case ezPropertyCategory::Set:
      case ezPropertyCategory::Map:
      {
        EZ_ASSERT_DEV(pProp->GetFlags().IsSet(ezPropertyFlags::StandardType) ==
                          pSpecificType->GetTypeFlags().IsSet(ezTypeFlags::StandardType),
                      "Property-Type missmatch!");
        EZ_ASSERT_DEV(pProp->GetFlags().IsSet(ezPropertyFlags::Class) == pSpecificType->GetTypeFlags().IsSet(ezTypeFlags::Class),
                      "If ezPropertyFlags::Class is set, the property type must be ezTypeFlags::Class and vise versa.");
      }
      break;
      case ezPropertyCategory::Function:
        EZ_REPORT_FAILURE("Functions need to be put into the EZ_BEGIN_FUNCTIONS / EZ_END_FUNCTIONS; block.");
        break;
    }
  }
}
 void Object::AddMesh(ezUniquePtr<Mesh> mesh)
 {
   EZ_ASSERT_DEBUG(m_MeshesHandles.IsEmpty(), "Can't add meshes to Pbrt::Object after it was initialized once.");
   m_MeshesData.PushBack(std::move(mesh));
 }
Example #28
0
void ezCameraVisualizerAdapter::Update()
{

  const ezCameraVisualizerAttribute* pAttr = static_cast<const ezCameraVisualizerAttribute*>(m_pVisualizerAttr);
  ezObjectAccessorBase* pObjectAccessor = GetObjectAccessor();

  float fNearPlane = 1.0f;
  float fFarPlane = 10.0f;
  ezInt32 iMode = 0;

  if (!pAttr->GetModeProperty().IsEmpty())
  {
    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetModeProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<ezInt32>(), "Invalid property bound to ezCameraVisualizerAttribute 'mode'");
    iMode = value.ConvertTo<ezInt32>();
  }

  if (!pAttr->GetNearPlaneProperty().IsEmpty())
  {
    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetNearPlaneProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<float>(), "Invalid property bound to ezCameraVisualizerAttribute 'near plane'");
    fNearPlane = value.ConvertTo<float>();
  }

  if (!pAttr->GetFarPlaneProperty().IsEmpty())
  {
    ezVariant value;
    pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetFarPlaneProperty()), value);

    EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<float>(), "Invalid property bound to ezCameraVisualizerAttribute 'far plane'");
    fFarPlane = value.ConvertTo<float>();
  }

  if (iMode == ezCameraMode::OrthoFixedHeight || iMode == ezCameraMode::OrthoFixedWidth)
  {
    float fDimensions = 1.0f;

    if (!pAttr->GetOrthoDimProperty().IsEmpty())
    {
      ezVariant value;
      pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetOrthoDimProperty()), value);

      EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<float>(), "Invalid property bound to ezCameraVisualizerAttribute 'ortho dim'");
      fDimensions = value.ConvertTo<float>();
    }

    {
      const float fRange = fFarPlane - fNearPlane;

      m_LocalTransformFrustum.m_qRotation.SetIdentity();
      m_LocalTransformFrustum.m_vScale.Set(fRange, fDimensions, fDimensions);
      m_LocalTransformFrustum.m_vPosition.Set(fNearPlane + fRange * 0.5f, 0, 0);
    }

    m_BoxGizmo.SetVisible(m_bVisualizerIsVisible);
    m_FrustumGizmo.SetVisible(false);
    m_NearPlaneGizmo.SetVisible(false);
    m_FarPlaneGizmo.SetVisible(false);

    m_LocalTransformNearPlane.SetIdentity();
    m_LocalTransformFarPlane.SetIdentity();
  }
  else
  {
    float fFOV = 45.0f;

    if (!pAttr->GetFovProperty().IsEmpty())
    {
      ezVariant value;
      pObjectAccessor->GetValue(m_pObject, GetProperty(pAttr->GetFovProperty()), value);

      EZ_ASSERT_DEBUG(value.IsValid() && value.CanConvertTo<float>(), "Invalid property bound to ezCameraVisualizerAttribute 'fov'");
      fFOV = value.ConvertTo<float>();
    }

    {
      const float fAngleScale = ezMath::Tan(ezAngle::Degree(fFOV) * 0.5f);
      const float fFrustumScale = ezMath::Min(fFarPlane, 10.0f);
      const float fFarPlaneScale = ezMath::Min(fFarPlane, 9.0f);
      ;

      // indicate whether the shown far plane is the actual distance, or just the maximum visualization distance
      m_FarPlaneGizmo.SetColor(fFarPlane > 9.0f ? ezColor::DodgerBlue : ezColor::PaleVioletRed);

      m_LocalTransformFrustum.m_qRotation.SetIdentity();
      m_LocalTransformFrustum.m_vScale.Set(fFrustumScale, fAngleScale * fFrustumScale, fAngleScale * fFrustumScale);
      m_LocalTransformFrustum.m_vPosition.Set(0, 0, 0);

      m_LocalTransformNearPlane.m_qRotation.SetFromAxisAndAngle(ezVec3(0, 1, 0), ezAngle::Degree(90));
      m_LocalTransformNearPlane.m_vScale.Set(fAngleScale * fNearPlane, fAngleScale * fNearPlane, 1);
      m_LocalTransformNearPlane.m_vPosition.Set(fNearPlane, 0, 0);

      m_LocalTransformFarPlane.m_qRotation.SetFromAxisAndAngle(ezVec3(0, 1, 0), ezAngle::Degree(90));
      m_LocalTransformFarPlane.m_vScale.Set(fAngleScale * fFarPlaneScale, fAngleScale * fFarPlaneScale, 1);
      m_LocalTransformFarPlane.m_vPosition.Set(fFarPlaneScale, 0, 0);
    }

    m_BoxGizmo.SetVisible(false);
    m_FrustumGizmo.SetVisible(m_bVisualizerIsVisible);
    m_NearPlaneGizmo.SetVisible(m_bVisualizerIsVisible);
    m_FarPlaneGizmo.SetVisible(m_bVisualizerIsVisible);
  }
}
Example #29
0
ezBitflags<ezAssetDocumentFlags>
ezPropertyAnimAssetDocumentManager::GetAssetDocumentTypeFlags(const ezDocumentTypeDescriptor* pDescriptor) const
{
  EZ_ASSERT_DEBUG(pDescriptor->m_pManager == this, "Given type descriptor is not part of this document manager!");
  return ezAssetDocumentFlags::AutoTransformOnSave;
}
Example #30
0
void ezImageConversionBase::RebuildConversionTable()
{
  s_conversionTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS);
  s_subConversionTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS);
  s_costTable.SetCount(ezImageFormat::NUM_FORMATS * ezImageFormat::NUM_FORMATS);

  for (ezUInt32 tableIdx = 0; tableIdx < s_conversionTable.GetCount(); tableIdx++)
  {
    s_conversionTable[tableIdx] = nullptr;
    s_costTable[tableIdx] = ezMath::BasicType<float>::GetInfinity();
  }

  // Prime conversion table with known conversions
  for (ezImageConversionBase* pConversion = ezImageConversionBase::GetFirstInstance(); pConversion; pConversion = pConversion->GetNextInstance())
  {
    for (ezUInt32 uiSubConversion = 0; uiSubConversion < pConversion->m_subConversions.GetCount(); uiSubConversion++)
    {
      const SubConversion& subConversion = pConversion->m_subConversions[uiSubConversion];

      if (subConversion.m_flags.IsSet(ezImageConversionFlags::InPlace))
      {
        EZ_ASSERT_DEBUG(ezImageFormat::GetBitsPerPixel(subConversion.m_sourceFormat) == ezImageFormat::GetBitsPerPixel(subConversion.m_targetFormat),
          "In-place conversions are only allowed between formats of the same number of bits per pixel");
        EZ_ASSERT_DEBUG(ezImageFormat::GetType(subConversion.m_sourceFormat) == ezImageFormat::GetType(subConversion.m_targetFormat),
          "In-place conversions are only allowed between formats of the same type");
      }

      ezUInt32 uiTableIndex = GetTableIndex(subConversion.m_sourceFormat, subConversion.m_targetFormat);

      // Use the cheapest known conversion for each combination in case there are multiple ones
      if (s_costTable[uiTableIndex] > GetConversionCost(subConversion.m_flags))
      {
        s_conversionTable[uiTableIndex] = pConversion;
        s_subConversionTable[uiTableIndex] = uiSubConversion;
        s_costTable[uiTableIndex] = GetConversionCost(subConversion.m_flags);
      }
    }
  }

  for (ezUInt32 i = 0; i < ezImageFormat::NUM_FORMATS; i++)
  {
    // Add copy-conversion (from and to same format)
    s_costTable[GetTableIndex(i, i)] = GetConversionCost(ezImageConversionFlags::InPlace);
  }

  // Straight from http://en.wikipedia.org/wiki/Floyd-Warshall_algorithm
  for (ezUInt32 k = 0; k < ezImageFormat::NUM_FORMATS; k++)
  {
    for (ezUInt32 i = 0; i < ezImageFormat::NUM_FORMATS; i++)
    {
      ezUInt32 uiTableIndexIK = GetTableIndex(i, k);
      for (ezUInt32 j = 0; j < ezImageFormat::NUM_FORMATS; j++)
      {
        ezUInt32 uiTableIndexIJ = GetTableIndex(i, j);
        ezUInt32 uiTableIndexKJ = GetTableIndex(k, j);
        if (s_costTable[uiTableIndexIK] + s_costTable[uiTableIndexKJ] < s_costTable[uiTableIndexIJ])
        {
          s_costTable[uiTableIndexIJ] = s_costTable[uiTableIndexIK] + s_costTable[uiTableIndexKJ];

          const ezImageConversionBase* pConversion = s_conversionTable[uiTableIndexIK];

          // To convert from format I to format J, first convert from I to K
          s_conversionTable[uiTableIndexIJ] = pConversion;
          s_subConversionTable[uiTableIndexIJ] = s_subConversionTable[uiTableIndexIK];
        }
      }
    }
  }

  s_bConversionTableValid = true;
}