博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
3dContactPointAnnotationTool开发日志(七)
阅读量:4597 次
发布时间:2019-06-09

本文共 5195 字,大约阅读时间需要 17 分钟。

  调了半天发现是逻辑错误,改了一下终于没那么奇怪了:

1.png
  但是有的接触点很明显跑偏了。再回顾一下自己是怎么求的,我是直接用的下面的代码求解一个点是否在另一个物体内部:

var bounds = uso.mesh.bounds;if (bounds.Contains(mesh.vertices[mesh.triangles[i+j]])){    xj = true;}

  这个bounds我又去unity文档上查了一下,发现它只是物体的包围盒,所以显然会得到多余的点,没办法只能再改了。

  既然unity没有自带的方法那就自己算得了,思路是对于一个给定点枚举另一个三维模型的三角面片通过面片法向量和面上一点通过点积的正负来判断。一个三角面片的法向量貌似是通过obj模型对应顶点对应的点的法向量相加再除以3得到的。然而网上的那个代码没有把顶点法向量读到gameobject中,于是自己修改如下:

using UnityEngine;using System.IO;using System.Linq;using System.Collections;using System.Collections.Generic;namespace Hont{    public static class ObjFormatAnalyzerFactory    {        public static List
AnalyzeToGameObject(string objFilePath) { if (!File.Exists(objFilePath)) return null; var objFormatAnalyzer = new ObjFormatAnalyzer(); objFormatAnalyzer.Analyze(File.ReadAllText(objFilePath)); int length = objFormatAnalyzer.ObjFaceBegin.Length; var re = new List
(); var sourceVertexArr = objFormatAnalyzer.VertexArr; var sourceVertexNormalArr = objFormatAnalyzer.VertexNormalArr; var sourceUVArr = objFormatAnalyzer.VertexTextureArr; var faceArr = objFormatAnalyzer.FaceArr; for (int objId = 0; objId < length; objId++) { var go = new GameObject(); go.name = objFormatAnalyzer.ObjName[objId]; var meshRenderer = go.AddComponent
(); var meshFilter = go.AddComponent
(); var mesh = new Mesh(); var vertexList = new List
(); var vertexNormalList = new List
(); var uvList = new List
(); int faceBeginId = objFormatAnalyzer.ObjFaceBegin[objId]; int faceEndId = faceArr.Length;//左闭右开 if (objId < length - 1) faceEndId = objFormatAnalyzer.ObjFaceBegin[objId + 1]; int triangleNum = 0; for (int i = faceBeginId; i < faceEndId; i++) if (faceArr[i].IsQuad) triangleNum += 6; else triangleNum += 3; var triangles = new int[triangleNum]; for (int i = faceBeginId, j = 0; i < faceEndId; i++) { var currentFace = faceArr[i]; triangles[j] = j; triangles[j + 1] = j + 1; triangles[j + 2] = j + 2; var vec = sourceVertexArr[currentFace.Points[0].VertexIndex - 1]; vertexList.Add(new Vector3(vec.X, vec.Y, vec.Z)); vec = sourceVertexNormalArr[currentFace.Points[0].VertexIndex - 1]; vertexNormalList.Add(new Vector3(vec.X, vec.Y, vec.Z)); var uv = sourceUVArr[currentFace.Points[0].TextureIndex - 1]; uvList.Add(new Vector2(uv.X, uv.Y)); vec = sourceVertexArr[currentFace.Points[1].VertexIndex - 1]; vertexList.Add(new Vector3(vec.X, vec.Y, vec.Z)); vec = sourceVertexNormalArr[currentFace.Points[1].VertexIndex - 1]; vertexNormalList.Add(new Vector3(vec.X, vec.Y, vec.Z)); uv = sourceUVArr[currentFace.Points[1].TextureIndex - 1]; uvList.Add(new Vector2(uv.X, uv.Y)); vec = sourceVertexArr[currentFace.Points[2].VertexIndex - 1]; vertexList.Add(new Vector3(vec.X, vec.Y, vec.Z)); vec = sourceVertexNormalArr[currentFace.Points[2].VertexIndex - 1]; vertexNormalList.Add(new Vector3(vec.X, vec.Y, vec.Z)); uv = sourceUVArr[currentFace.Points[2].TextureIndex - 1]; uvList.Add(new Vector2(uv.X, uv.Y)); if (currentFace.IsQuad) { triangles[j + 3] = j + 3; triangles[j + 4] = j + 4; triangles[j + 5] = j + 5; j += 3; vec = sourceVertexArr[currentFace.Points[0].VertexIndex - 1]; vertexList.Add(new Vector3(vec.X, vec.Y, vec.Z)); vec = sourceVertexNormalArr[currentFace.Points[0].VertexIndex - 1]; vertexNormalList.Add(new Vector3(vec.X, vec.Y, vec.Z)); uv = sourceUVArr[currentFace.Points[0].TextureIndex - 1]; uvList.Add(new Vector2(uv.X, uv.Y)); vec = sourceVertexArr[currentFace.Points[2].VertexIndex - 1]; vertexList.Add(new Vector3(vec.X, vec.Y, vec.Z)); vec = sourceVertexNormalArr[currentFace.Points[2].VertexIndex - 1]; vertexNormalList.Add(new Vector3(vec.X, vec.Y, vec.Z)); uv = sourceUVArr[currentFace.Points[2].TextureIndex - 1]; uvList.Add(new Vector2(uv.X, uv.Y)); vec = sourceVertexArr[currentFace.Points[3].VertexIndex - 1]; vertexList.Add(new Vector3(vec.X, vec.Y, vec.Z)); vec = sourceVertexNormalArr[currentFace.Points[3].VertexIndex - 1]; vertexNormalList.Add(new Vector3(vec.X, vec.Y, vec.Z)); uv = sourceUVArr[currentFace.Points[3].TextureIndex - 1]; uvList.Add(new Vector2(uv.X, uv.Y)); } j += 3; } mesh.vertices = vertexList.ToArray(); mesh.normals = vertexNormalList.ToArray(); mesh.uv = uvList.ToArray(); mesh.triangles = triangles; meshFilter.mesh = mesh; meshRenderer.material = new Material(Shader.Find("Standard")); //meshRenderer.material = new Material(Shader.Find("UCLA Game Lab/Wireframe/Single-Sided")); re.Add(go); } return re; } }}

  发现得到模型的光照效果也不一样了,加入法向量之后的效果:

2.png
  之前的没加法向量的效果:
3.png
  然后拿这些法向量来算,发现压根算不出接触点来。到底是什么问题呢?用Debug.DrawLine图形化显示一下(只能在scene中看到线),发现根本不是我想的那样。

Debug.DrawLine(c, c+n/10,Color.red,10000);

  顶点和顶点法向量:

4.png
  三顶点相加/3和顶点法向量相加/3:
5.png
  貌似这个法向量是只影响光照的,和几何半毛钱关系没有,所以只能用叉积来算了。
  用叉积算完还是不对,再图形化看看,发现有的三角面片竟然有两个朝向的法向量,简直无语。
6.png
  看了一下obj模型,竟然还有这样的三角面片,明明是同一个但是顺序相反,真是坑爹。
7.png
  所以只能再结合一下光照法向量了,毕竟他们都是朝外的。
  实验发现他们并不都是朝外的,GG!
  而且回想一下发现这个方法只对凸的物体有用,那些不规则的物体是不能用这种方法的。
  为何不用射线法呢?具体怎么实现明天再弄吧。

转载于:https://www.cnblogs.com/yaoling1997/p/9960087.html

你可能感兴趣的文章
jquery 编程的最佳实践
查看>>
MeetMe
查看>>
IP报文格式及各字段意义
查看>>
(转载)rabbitmq与springboot的安装与集成
查看>>
C2. Power Transmission (Hard Edition)(线段相交)
查看>>
STM32F0使用LL库实现SHT70通讯
查看>>
Atitit. Xss 漏洞的原理and应用xss木马
查看>>
MySQL源码 数据结构array
查看>>
(文件过多时)删除目录下全部文件
查看>>
T-SQL函数总结
查看>>
python 序列:列表
查看>>
web移动端
查看>>
pythonchallenge闯关 第13题
查看>>
linux上很方便的上传下载文件工具rz和sz使用介绍
查看>>
React之特点及常见用法
查看>>
【WEB前端经验之谈】时间一年半,或沉淀、或从零开始。
查看>>
优云软件助阵GOPS·2017全球运维大会北京站
查看>>
linux 装mysql的方法和步骤
查看>>
poj3667(线段树区间合并&区间查询)
查看>>
51nod1241(连续上升子序列)
查看>>