// 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; }
//_______________________________________________________________________________________________________ void Draw(void) { ShapeHeader(); GetVertexes(); GetNormals(); fprintf(TIVFile::File, "\tSeparator {\n"); Draw2File(); fprintf(TIVFile::File, "\t}\n"); }
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"); }
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"); } }
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"); } }
void Mesh::GetNormals(int index, Vector *V) { GetNormals(faces[index].points, V); }
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())); } }
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; }