コード例 #1
0
ファイル: LoadMeshFromCollada.cpp プロジェクト: Aatch/bullet3
void readLibraryGeometries(TiXmlDocument& doc, btAlignedObjectArray<GLInstanceGraphicsShape>& visualShapes, btHashMap<btHashString,int>& name2Shape, float extraScaling) 
{
	btHashMap<btHashString,TiXmlElement* > allSources;
	btHashMap<btHashString,VertexSource> vertexSources;
	for(TiXmlElement* geometry = doc.RootElement()->FirstChildElement("library_geometries")->FirstChildElement("geometry");
			geometry != NULL; geometry = geometry->NextSiblingElement("geometry")) 
	{
		btAlignedObjectArray<btVector3> vertexPositions;
		btAlignedObjectArray<btVector3> vertexNormals;
		btAlignedObjectArray<int> indices;

		const char* geometryName = geometry->Attribute("id");
		for (TiXmlElement* mesh = geometry->FirstChildElement("mesh");(mesh != NULL); mesh = mesh->NextSiblingElement("mesh")) 
		{
			TiXmlElement* vertices2 = mesh->FirstChildElement("vertices");
			
			for (TiXmlElement* source = mesh->FirstChildElement("source");source != NULL;source = source->NextSiblingElement("source")) 
			{
				const char* srcId= source->Attribute("id");
//				printf("source id=%s\n",srcId);
				allSources.insert(srcId,source);
			}
			const char* vertexId = vertices2->Attribute("id");
			//printf("vertices id=%s\n",vertexId);
			VertexSource vs;
			for(TiXmlElement* input = vertices2->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input")) 
			{
				const char* sem = input->Attribute("semantic");
				std::string semName(sem);
//					printf("sem=%s\n",sem);
				const char* src = input->Attribute("source");
//					printf("src=%s\n",src);
				const char* srcIdRef = input->Attribute("source");
				std::string source_name;
				source_name = std::string(srcIdRef);
				source_name = source_name.erase(0, 1);
				if (semName=="POSITION")
				{
					vs.m_positionArrayId = source_name;
				}
				if (semName=="NORMAL")
				{
					vs.m_normalArrayId = source_name;
				}
			}
			vertexSources.insert(vertexId,vs);

			for (TiXmlElement* primitive = mesh->FirstChildElement("triangles"); primitive; primitive = primitive->NextSiblingElement("triangles"))
			{
				std::string positionSourceName;
				std::string normalSourceName;
				int primitiveCount;
				primitive->QueryIntAttribute("count", &primitiveCount);
				bool positionAndNormalInVertex=false;
				int indexStride=1;
				int posOffset = 0;
				int normalOffset = 0;
				int numIndices = 0;
				{
					for (TiXmlElement* input = primitive->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input")) 
					{
						const char* sem = input->Attribute("semantic");
						std::string semName(sem);
						int offset = atoi(input->Attribute("offset"));
						if ((offset+1)>indexStride)
							indexStride=offset+1;
						//printf("sem=%s\n",sem);
						const char* src = input->Attribute("source");
						//printf("src=%s\n",src);
						const char* srcIdRef = input->Attribute("source");
						std::string source_name;
						source_name = std::string(srcIdRef);
						source_name = source_name.erase(0, 1);
							
						if (semName=="VERTEX")
						{
							//now we have POSITION and possibly NORMAL too, using same index array (<p>)
							VertexSource* vs = vertexSources[source_name.c_str()];
							if (vs->m_positionArrayId.length())
							{
								positionSourceName = vs->m_positionArrayId;
								posOffset = offset;
							}
							if (vs->m_normalArrayId.length())
							{
								normalSourceName = vs->m_normalArrayId;
								normalOffset  = offset;
								positionAndNormalInVertex = true;
							}
						}
						if (semName=="NORMAL")
						{
							btAssert(normalSourceName.length()==0);
							normalSourceName = source_name;
							normalOffset  = offset;
							positionAndNormalInVertex = false;
						}
					}
					numIndices = primitiveCount * 3; 
				}
				btAlignedObjectArray<float> positionFloatArray;
				int posStride=1;
				TiXmlElement** sourcePtr = allSources[positionSourceName.c_str()];
				if (sourcePtr)
				{
					readFloatArray(*sourcePtr,positionFloatArray, posStride);
				}
				btAlignedObjectArray<float> normalFloatArray;
				int normalStride=1;
				sourcePtr = allSources[normalSourceName.c_str()];
				if (sourcePtr)
				{
					readFloatArray(*sourcePtr,normalFloatArray,normalStride);
				}
				btAlignedObjectArray<int> curIndices;
				curIndices.reserve(numIndices*indexStride);
				TokenIntArray adder(curIndices);
				tokenize(primitive->FirstChildElement("p")->GetText(),adder);
				assert(curIndices.size() == numIndices*indexStride);
				int indexOffset = vertexPositions.size();

				for(int index=0; index<numIndices; index++) 
				{
					int posIndex = curIndices[index*indexStride+posOffset];
					int normalIndex = curIndices[index*indexStride+normalOffset];
					vertexPositions.push_back(btVector3(extraScaling*positionFloatArray[posIndex*3+0],
						extraScaling*positionFloatArray[posIndex*3+1],
						extraScaling*positionFloatArray[posIndex*3+2]));
							
					if (normalFloatArray.size() && (normalFloatArray.size()>normalIndex))
					{
						vertexNormals.push_back(btVector3(normalFloatArray[normalIndex*3+0],
															normalFloatArray[normalIndex*3+1],
															normalFloatArray[normalIndex*3+2]));
					} else
					{
						//add a dummy normal of length zero, so it is easy to detect that it is an invalid normal
						vertexNormals.push_back(btVector3(0,0,0));
					}
				}
				int curNumIndices = indices.size();
				indices.resize(curNumIndices+numIndices);
				for(int index=0; index<numIndices; index++) 
				{
					indices[curNumIndices+index] = index+indexOffset;
				}
			}//if(primitive != NULL) 
		}//for each mesh
		
		int shapeIndex = visualShapes.size();
		GLInstanceGraphicsShape& visualShape = visualShapes.expand();
		{
			visualShape.m_vertices = new b3AlignedObjectArray<GLInstanceVertex>;
			visualShape.m_indices = new b3AlignedObjectArray<int>;
			int indexBase = 0;

			btAssert(vertexNormals.size()==vertexPositions.size());
			for (int v=0;v<vertexPositions.size();v++)
			{
				GLInstanceVertex vtx;
				vtx.xyzw[0] = vertexPositions[v].x();
				vtx.xyzw[1] = vertexPositions[v].y();
				vtx.xyzw[2] = vertexPositions[v].z();
				vtx.xyzw[3] = 1.f;
				vtx.normal[0] = vertexNormals[v].x();
				vtx.normal[1] = vertexNormals[v].y();
				vtx.normal[2] = vertexNormals[v].z();
				vtx.uv[0] = 0.5f;
				vtx.uv[1] = 0.5f;
				visualShape.m_vertices->push_back(vtx);
			}

			for (int index=0;index<indices.size();index++)
			{
				visualShape.m_indices->push_back(indices[index]+indexBase);
			}
			
			
			printf(" index_count =%dand vertexPositions.size=%d\n",indices.size(), vertexPositions.size());
			indexBase=visualShape.m_vertices->size();
			visualShape.m_numIndices = visualShape.m_indices->size();
			visualShape.m_numvertices = visualShape.m_vertices->size();
		}
		printf("geometry name=%s\n",geometryName);
		name2Shape.insert(geometryName,shapeIndex);
		

	}//for each geometry
}
コード例 #2
0
QVector<VertexInputAttribute> CommonPipelineState::GetVertexInputs()
{
  if(LogLoaded())
  {
    if(IsLogD3D11())
    {
      uint32_t byteOffs[128] = {};

      auto &layouts = m_D3D11->m_IA.layouts;

      QVector<VertexInputAttribute> ret(layouts.count);
      for(int i = 0; i < layouts.count; i++)
      {
        QString semName(layouts[i].SemanticName);

        bool needsSemanticIdx = false;
        for(int j = 0; j < layouts.count; j++)
        {
          if(i != j && !semName.compare(QString(layouts[j].SemanticName), Qt::CaseInsensitive))
          {
            needsSemanticIdx = true;
            break;
          }
        }

        uint32_t offs = layouts[i].ByteOffset;
        if(offs == UINT32_MAX)    // APPEND_ALIGNED
          offs = byteOffs[layouts[i].InputSlot];
        else
          byteOffs[layouts[i].InputSlot] = offs = layouts[i].ByteOffset;

        byteOffs[layouts[i].InputSlot] +=
            layouts[i].Format.compByteWidth * layouts[i].Format.compCount;

        ret[i].Name = semName + (needsSemanticIdx ? QString::number(layouts[i].SemanticIndex) : "");
        ret[i].VertexBuffer = (int)layouts[i].InputSlot;
        ret[i].RelativeByteOffset = offs;
        ret[i].PerInstance = layouts[i].PerInstance;
        ret[i].InstanceRate = (int)layouts[i].InstanceDataStepRate;
        ret[i].Format = layouts[i].Format;
        memset(&ret[i].GenericValue, 0, sizeof(PixelValue));
        ret[i].Used = false;

        if(m_D3D11->m_IA.Bytecode != NULL)
        {
          rdctype::array<SigParameter> &sig = m_D3D11->m_IA.Bytecode->InputSig;
          for(int ia = 0; ia < sig.count; ia++)
          {
            if(!semName.compare(QString(sig[ia].semanticName), Qt::CaseInsensitive) &&
               sig[ia].semanticIndex == layouts[i].SemanticIndex)
            {
              ret[i].Used = true;
              break;
            }
          }
        }
      }

      return ret;
    }
    else if(IsLogD3D12())
    {
      uint32_t byteOffs[128] = {};

      auto &layouts = m_D3D12->m_IA.layouts;

      QVector<VertexInputAttribute> ret(layouts.count);
      for(int i = 0; i < layouts.count; i++)
      {
        QString semName(layouts[i].SemanticName);

        bool needsSemanticIdx = false;
        for(int j = 0; j < layouts.count; j++)
        {
          if(i != j && !semName.compare(QString(layouts[j].SemanticName), Qt::CaseInsensitive))
          {
            needsSemanticIdx = true;
            break;
          }
        }

        uint32_t offs = layouts[i].ByteOffset;
        if(offs == UINT32_MAX)    // APPEND_ALIGNED
          offs = byteOffs[layouts[i].InputSlot];
        else
          byteOffs[layouts[i].InputSlot] = offs = layouts[i].ByteOffset;

        byteOffs[layouts[i].InputSlot] +=
            layouts[i].Format.compByteWidth * layouts[i].Format.compCount;

        ret[i].Name = semName + (needsSemanticIdx ? QString::number(layouts[i].SemanticIndex) : "");
        ret[i].VertexBuffer = (int)layouts[i].InputSlot;
        ret[i].RelativeByteOffset = offs;
        ret[i].PerInstance = layouts[i].PerInstance;
        ret[i].InstanceRate = (int)layouts[i].InstanceDataStepRate;
        ret[i].Format = layouts[i].Format;
        memset(&ret[i].GenericValue, 0, sizeof(PixelValue));
        ret[i].Used = false;

        if(m_D3D12->m_VS.ShaderDetails != NULL)
        {
          rdctype::array<SigParameter> &sig = m_D3D12->m_VS.ShaderDetails->InputSig;
          for(int ia = 0; ia < sig.count; ia++)
          {
            if(!semName.compare(QString(sig[ia].semanticName), Qt::CaseInsensitive) &&
               sig[ia].semanticIndex == layouts[i].SemanticIndex)
            {
              ret[i].Used = true;
              break;
            }
          }
        }
      }

      return ret;
    }
    else if(IsLogGL())
    {
      auto &attrs = m_GL->m_VtxIn.attributes;

      int num = 0;
      for(int i = 0; i < attrs.count; i++)
      {
        int attrib = -1;
        if(m_GL->m_VS.ShaderDetails != NULL)
          attrib = m_GL->m_VS.BindpointMapping.InputAttributes[i];
        else
          attrib = i;

        if(attrib >= 0)
          num++;
      }

      int a = 0;
      QVector<VertexInputAttribute> ret(attrs.count);
      for(int i = 0; i < attrs.count && a < num; i++)
      {
        ret[a].Name = QString("attr%1").arg(i);
        memset(&ret[a].GenericValue, 0, sizeof(PixelValue));
        ret[a].VertexBuffer = (int)attrs[i].BufferSlot;
        ret[a].RelativeByteOffset = attrs[i].RelativeOffset;
        ret[a].PerInstance = m_GL->m_VtxIn.vbuffers[attrs[i].BufferSlot].Divisor > 0;
        ret[a].InstanceRate = (int)m_GL->m_VtxIn.vbuffers[attrs[i].BufferSlot].Divisor;
        ret[a].Format = attrs[i].Format;
        ret[a].Used = true;

        if(m_GL->m_VS.ShaderDetails != NULL)
        {
          int attrib = m_GL->m_VS.BindpointMapping.InputAttributes[i];

          if(attrib >= 0 && attrib < m_GL->m_VS.ShaderDetails->InputSig.count)
            ret[a].Name = m_GL->m_VS.ShaderDetails->InputSig[attrib].varName;

          if(attrib == -1)
            continue;

          if(!attrs[i].Enabled)
          {
            uint32_t compCount = m_GL->m_VS.ShaderDetails->InputSig[attrib].compCount;
            FormatComponentType compType = m_GL->m_VS.ShaderDetails->InputSig[attrib].compType;

            for(uint32_t c = 0; c < compCount; c++)
            {
              if(compType == eCompType_Float)
                ret[a].GenericValue.value_f[c] = attrs[i].GenericValue.f[c];
              else if(compType == eCompType_UInt)
                ret[a].GenericValue.value_u[c] = attrs[i].GenericValue.u[c];
              else if(compType == eCompType_SInt)
                ret[a].GenericValue.value_i[c] = attrs[i].GenericValue.i[c];
              else if(compType == eCompType_UScaled)
                ret[a].GenericValue.value_f[c] = (float)attrs[i].GenericValue.u[c];
              else if(compType == eCompType_SScaled)
                ret[a].GenericValue.value_f[c] = (float)attrs[i].GenericValue.i[c];
            }

            ret[a].PerInstance = false;
            ret[a].InstanceRate = 0;
            ret[a].Format.compByteWidth = 4;
            ret[a].Format.compCount = compCount;
            ret[a].Format.compType = compType;
            ret[a].Format.special = false;
            ret[a].Format.srgbCorrected = false;
          }
        }

        a++;
      }

      return ret;
    }
    else if(IsLogVK())
    {
      auto &attrs = m_Vulkan->VI.attrs;

      int num = 0;
      for(int i = 0; i < attrs.count; i++)
      {
        int attrib = -1;
        if(m_Vulkan->VS.ShaderDetails != NULL)
        {
          if(attrs[i].location < (uint32_t)m_Vulkan->VS.BindpointMapping.InputAttributes.count)
            attrib = m_Vulkan->VS.BindpointMapping.InputAttributes[attrs[i].location];
        }
        else
          attrib = i;

        if(attrib >= 0)
          num++;
      }

      int a = 0;
      QVector<VertexInputAttribute> ret(num);
      for(int i = 0; i < attrs.count && a < num; i++)
      {
        ret[a].Name = QString("attr%1").arg(i);
        memset(&ret[a].GenericValue, 0, sizeof(PixelValue));
        ret[a].VertexBuffer = (int)attrs[i].binding;
        ret[a].RelativeByteOffset = attrs[i].byteoffset;
        ret[a].PerInstance = false;
        if(attrs[i].binding < (uint32_t)m_Vulkan->VI.binds.count)
          ret[a].PerInstance = m_Vulkan->VI.binds[attrs[i].binding].perInstance;
        ret[a].InstanceRate = 1;
        ret[a].Format = attrs[i].format;
        ret[a].Used = true;

        if(m_Vulkan->VS.ShaderDetails != NULL)
        {
          int attrib = -1;

          if(attrs[i].location < (uint32_t)m_Vulkan->VS.BindpointMapping.InputAttributes.count)
            attrib = m_Vulkan->VS.BindpointMapping.InputAttributes[attrs[i].location];

          if(attrib >= 0 && attrib < m_Vulkan->VS.ShaderDetails->InputSig.count)
            ret[a].Name = m_Vulkan->VS.ShaderDetails->InputSig[attrib].varName;

          if(attrib == -1)
            continue;
        }

        a++;
      }

      return ret;
    }
  }

  return QVector<VertexInputAttribute>();
}