Пример #1
0
// Returns true if there is no collision, and false if there is a collision.
bool TestSAT(AABB a, AABB b)
{
	// Since these are AABB collisions, we can easily determine the normals. That said, this was left this way for understanding and future implementation.
	// The first step is to get the normals for the two colliding objects, as these will be the axes on which we test for collisions.
	std::vector<glm::vec3> aNormals = GetNormals(a);
	std::vector<glm::vec3> bNormals = GetNormals(b);
	
	// A quick method that exists for getting the points of the AABB. In a regular implementation, we might instead pass in the actual points to this algorithm, skipping
	// this step.
	std::vector<glm::vec3> aPoints = GetPoints(a);
	std::vector<glm::vec3> bPoints = GetPoints(b);

	// This boolean gets returned, and will be true if there is no collision.
	bool isSeparated = false;

	// For each normal
	for (int i = 0; i < aNormals.size(); i++)
	{
		// Get the Min and Max projections for each object along the normal.
		float aMin, aMax;
		GetMinMax(aPoints, aNormals[i], aMin, aMax);

		float bMin, bMax;
		GetMinMax(bPoints, aNormals[i], bMin, bMax);

		// If the maximum projection of one of the objects is less than the minimum projection of the other object, then we can determine that there is a separation 
		// along this axis. Thus, we set isSeparated to true and break out of the for loop.
		isSeparated = aMax < bMin || bMax < aMin;
		if (isSeparated) break;
	}

	// This only runs if we still haven't proven that there is a separation between the two objects.
	// SAT is an optimistic algorithm in that it will stop the moment it determines there isn't a collision, and as such the less collisions there are the faster it will run.
	if (!isSeparated)
	{
		// Loop through the normals for the second object.
		// Note that since this is an AABB, the normals will be the same as the previous object. Again, this is left for future implementation and understanding.
		// The process below is exactly the same as above, only with object b's normals instead of object a.
		for (int i = 0; i < bNormals.size(); i++)
		{
			float aMin, aMax;
			GetMinMax(aPoints, bNormals[i], aMin, aMax);

			float bMin, bMax;
			GetMinMax(bPoints, bNormals[i], bMin, bMax);

			isSeparated = aMax < bMin || bMax < aMin;
			if (isSeparated) break;
		}
	}

	// At this point, isSeparated has been tested against each normal. If it has been set to true, then there is a separation. If it is false, that means none of the axes 
	// were separated, and there is a collision.
	return isSeparated;
}
Пример #2
0
//_______________________________________________________________________________________________________
   void Draw(void) {

      ShapeHeader();
      GetVertexes();

      GetNormals();	

      fprintf(TIVFile::File, "\tSeparator {\n");

      Draw2File();

      fprintf(TIVFile::File, "\t}\n");

   }   	
Пример #3
0
   void Draw(void) {
      Prep();	
      ShapeHeader();
      GetVertexes();
      GetNormals();	
      NormalCorrection();	

      fprintf(TIVFile::File, "\tSeparator {\n");

      Draw2File();

      for(int i = 1; i < TIVTube::NCDiv; i ++) fprintf(
         TIVFile::File,
         "\t    Rotation { rotation 0 0 1 %f }\n"
         "\t    Separator { USE TubeUpperSector }\n",
         TIVTube::Xa
         );
      fprintf(TIVFile::File, "\t}\n");

   }   	
Пример #4
0
   void Draw(void) {
      TIVTubs::Prep();


      for(int i = 0; i < TIVTube::NDiv; i++) {
         fprintf(TIVFile::File, "\tSeparator {\n");

         ShapeHeader();
         GetVertexes(i);
         GetNormals(i);
         //	    NormalCorrection();


         fprintf(TIVFile::File, "\tSeparator {\n");

         Draw2File();				

         fprintf(TIVFile::File, "\t}\n");
         fprintf(TIVFile::File, "\t}\n");
      } 
   }
Пример #5
0
   void Draw(void) {
      for(int i = 0; i < Nz - 1; i++) {
         if(vDz[i] == vDz[i + 1]) continue;  
         Prep(i);
         GetVertexes(i);
         GetNormals();	
         TIVCone::NormalCorrection();	

         fprintf(TIVFile::File, "\tSeparator {\n");

         Draw2File();

         for(int j = 1; j < TIVTube::NCDiv; j++) fprintf(
            TIVFile::File,
            "\t    Rotation { rotation 0 0 1 %f }\n"
            "\t    Separator { USE TubeUpperSector }\n",
            TIVTube::Xa
            );
         fprintf(TIVFile::File, "\t}\n");

      }

   }
Пример #6
0
void Mesh::GetNormals(int index, Vector *V)
{
	GetNormals(faces[index].points, V);
}
Пример #7
0
void AasRenderer::Render(gfx::AnimatedModel *model,
	const gfx::AnimatedModelParams& params,
	gsl::span<Light3d> lights,
	const MdfRenderOverrides *materialOverrides) {

	// Find or create render caching data for the model
	auto &renderData = mRenderDataCache[model->GetHandle()];
	if (!renderData) {
		renderData = std::make_unique<AasRenderData>();
	}
	
	auto materialIds(model->GetSubmeshes());
	for (size_t i = 0; i < materialIds.size(); ++i) {
		auto materialId = materialIds[i];
		auto submesh(model->GetSubmesh(params, i));
		
		// Remove special material marker in the upper byte and only 
		// use the actual shader registration id
		materialId &= 0x00FFFFFF;

		// Usually this should not happen, since it means there's  
		// an unbound replacement material
		if (materialId == 0) {
			continue;
		}

		// if material was not found
		if (materialId == 0x00FFFFFF) {
			continue;
		}

		auto material = mMdfFactory.GetById(materialId);
		
		if (!material) {
			logger->error("Legacy shader with id {} wasn't found.", materialId);
			continue;
		}

		material->Bind(mDevice, lights, materialOverrides);

		// Do we have to recalculate the normals?
		if (material->GetSpec()->recalculateNormals) {
			RecalcNormals(
				submesh->GetVertexCount(),
				submesh->GetPositions().data(),
				submesh->GetNormals().data(),
				submesh->GetPrimitiveCount(),
				submesh->GetIndices().data()
			);
		}

		auto &submeshData = GetSubmeshData(*renderData, i, *submesh);
		submeshData.binding.Bind();

		auto d3d = mDevice.GetDevice();
		d3d->SetIndices(submeshData.idxBuffer->GetBuffer());
		D3DLOG(d3d->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, submesh->GetVertexCount(), 0, submesh->GetPrimitiveCount()));

	}

}
Пример #8
0
  vtkDebugMacro(<<"Generating glyphs");

  pts = vtkIdList::New();
  pts->Allocate(VTK_CELL_SIZE);

  if (!input)
    {
    vtkErrorMacro(<<"No input");
    return;
    }

  pd = input->GetPointData();
  inScalars = pd->GetScalars(this->InputScalarsSelection);
  inVectors = pd->GetVectors(this->InputVectorsSelection);
  inNormals = pd->GetNormals(this->InputNormalsSelection);

  inScalars_forColoring = pd->GetArray(this->ScalarsForColoring);
  inScalars_forScaling  = pd->GetArray(this->ScalarsForScaling);
  inVectors_forColoring = pd->GetArray(this->VectorsForColoring);
  inVectors_forScaling  = pd->GetArray(this->VectorsForScaling);
  inTensors_forScaling  = pd->GetArray(this->TensorsForScaling);

  inOrigNodes = pd->GetArray("avtOriginalNodeNumbers");
  inOrigCells = pd->GetArray("avtOriginalCellNumbers");

  vtkDataArray* temp = 0;
  if (pd)
    {
    temp = pd->GetArray("avtGhostZones");
    }
	std::shared_ptr<Mesh> FBXConverter::LoadMesh(FbxMesh* fbxMesh)
	{
		assert(fbxMesh->GetLayerCount() > 0);

		auto node = fbxMesh->GetNode();
		auto layer = fbxMesh->GetLayer(0);

		if (layer->GetNormals() == nullptr)
		{
			fbxMesh->GenerateNormals(true);
		}

		auto uvs = layer->GetUVs();
		auto vcolors = layer->GetVertexColors();
		auto normals = layer->GetNormals();
		auto binormals = layer->GetBinormals();
		auto materials = layer->GetMaterials();

		auto controlPoints = fbxMesh->GetControlPoints();
		auto controlPointsCount = fbxMesh->GetControlPointsCount();

		auto polygonCount = fbxMesh->GetPolygonCount();

		std::vector<FbxFace> faces;

		// Load weights
		std::vector<BoneConnector> bcs_temp;
		std::vector<Vertex> vs_temp;
		LoadSkin(fbxMesh, bcs_temp, vs_temp);

		// generate face vertex
		int32_t vertexID = 0;
		for (int32_t polygonIndex = 0; polygonIndex < polygonCount; polygonIndex++)
		{
			int polygonPointCount = fbxMesh->GetPolygonSize(polygonIndex);

			FbxFace face;

			for (int32_t polygonPointIndex = 0; polygonPointIndex < polygonPointCount; polygonPointIndex++)
			{
				auto ctrlPointIndex = fbxMesh->GetPolygonVertex(polygonIndex, polygonPointIndex);

				Vertex v;

				v.Position = LoadPosition(fbxMesh, ctrlPointIndex);
				
				v.Weights = vs_temp[ctrlPointIndex].Weights;

				if (normals != nullptr)
				{
					v.Normal = LoadNormal(normals, vertexID, ctrlPointIndex);
				}
		
				if (uvs != nullptr)
				{
					v.UV = LoadUV(fbxMesh, uvs, vertexID, ctrlPointIndex, polygonIndex, polygonPointIndex);
				}
				else
				{
					// Auto generated
					v.UV[0] = v.Position[0] + v.Position[2];
					v.UV[1] = v.Position[1];
				}

				if (vcolors != nullptr)
				{
					v.VertexColor = LoadVertexColor(fbxMesh, vcolors, vertexID, ctrlPointIndex, polygonIndex, polygonPointIndex);
				}

				face.Vertecies.push_back(v);
				vertexID++;
			}

			faces.push_back(face);
		}



		// 面の表裏入れ替え
		for (auto& face : faces)
		{
			std::reverse(face.Vertecies.begin(), face.Vertecies.end());
		}

		// メッシュで使用可能な形式に変換
	
		// 頂点変換テーブル作成
		int32_t vInd = 0;
		std::map<Vertex, int32_t> v2ind;
		std::map<int32_t, Vertex> ind2v;

		for (auto& face : faces)
		{
			for (int32_t vi = 0; vi < (int32_t)face.Vertecies.size(); vi++)
			{
				auto vertex = face.Vertecies[vi];

				auto it = v2ind.find(vertex);
				if (it == v2ind.end())
				{
					v2ind[vertex] = vInd;
					ind2v[vInd] = vertex;
					vInd++;
				}
			}
		}

		// 設定
		auto mesh = std::make_shared<Mesh>();
		mesh->Name = node->GetName();
		mesh->BoneConnectors = bcs_temp;

		mesh->Vertexes.resize(vInd);
		for (auto& iv : ind2v)
		{
			mesh->Vertexes[iv.first] = iv.second;
		}

		for (auto& face : faces)
		{
			if (face.Vertecies.size() < 3) continue;

			if (face.Vertecies.size() == 3)
			{
				Face f;
				f.Index[0] = v2ind[face.Vertecies[0]];
				f.Index[1] = v2ind[face.Vertecies[1]];
				f.Index[2] = v2ind[face.Vertecies[2]];
				mesh->Faces.push_back(f);
			}
			
			if (face.Vertecies.size() == 4)
			{
				Face f0;
				f0.Index[0] = v2ind[face.Vertecies[0]];
				f0.Index[1] = v2ind[face.Vertecies[1]];
				f0.Index[2] = v2ind[face.Vertecies[2]];
				mesh->Faces.push_back(f0);

				Face f1;
				f1.Index[0] = v2ind[face.Vertecies[0]];
				f1.Index[1] = v2ind[face.Vertecies[2]];
				f1.Index[2] = v2ind[face.Vertecies[3]];
				mesh->Faces.push_back(f1);
			}
		}

		// Binormal,Tangent計算
		std::map<int32_t, VertexNormals> vInd2Normals;

		for (const auto& face : mesh->Faces)
		{
			FbxVector4 binormal, tangent;
			CalcTangentSpace(
				mesh->Vertexes[face.Index[0]],
				mesh->Vertexes[face.Index[1]],
				mesh->Vertexes[face.Index[2]],
				binormal,
				tangent);

			for (auto i = 0; i < 3; i++)
			{
				vInd2Normals[face.Index[i]].Binormal += binormal;
				vInd2Normals[face.Index[i]].Tangent += tangent;
				vInd2Normals[face.Index[i]].Count += 1;
			}
		}

		for (auto& vn : vInd2Normals)
		{
			vn.second.Binormal /= vn.second.Count;
			vn.second.Tangent /= vn.second.Count;
		}

		for (auto& vn : vInd2Normals)
		{
			mesh->Vertexes[vn.first].Binormal = vn.second.Binormal;
			mesh->Vertexes[vn.first].Tangent = vn.second.Tangent;

			// 適当な値を代入する
			if (mesh->Vertexes[vn.first].Binormal.Length() == 0.0f)
			{
				if (mesh->Vertexes[vn.first].Normal != FbxVector4(1, 0, 0))
				{
					mesh->Vertexes[vn.first].Binormal = FbxVector4(1, 0, 0);
					mesh->Vertexes[vn.first].Tangent = FbxVector4(0, 1, 0);
				}
				else
				{
					mesh->Vertexes[vn.first].Binormal = FbxVector4(0, 1, 0);
					mesh->Vertexes[vn.first].Tangent = FbxVector4(1, 0, 0);
				}
			}
		}

		return mesh;
	}