当前位置: 首页 > news >正文

lyo blog3D文章集锦

lyo blog关闭了,好文章做个备份

---------------------------------------

Skinned Mesh in M3G

Filed under: Programming

Skinned Mesh,就是根据skeleton去变换顶点,通过addTransform函数将Vertex和bone绑定,Specification中给出了计算式子:

Denote the set of nodes (bones) associated with a vertex by { N1, N2, …, NN }.
Denote by Mi the transformation from the local coordinate system of node Nito a reference coordinate system.
The choice of the reference coordinate system is not critical; depending on the implementation,
good choices may include the world coordinate system, the coordinate system of the SkinnedMesh node,
or the coordinate system of the current camera. Finally, let us denote the weight associated with node Ni as Wi.
The blended position of a vertex in the reference coordinate system is then:

v‘ = sum [ w i M i B i v ]

其中,

  • 0 <= i < N, 其中N 是和顶点v 关联的bone个数;
  • v 是VertexBuffer中初始的顶点位置;
  • Bi是"at rest"变换,即从SkinnedMesh到顶点bone的初始变换矩阵,可以用Node.getTransformTo(bone, transform)取得;
  • Mi当前顶点bone到参考坐标系的变换矩阵,我们取SkinnedMesh的坐标系,这样得到的是一个标准的Mesh,方便调用渲染;
  • wi is the normalized weight of bone Ni, computed as wi = Wi / (W1 + … + WN).

Bi在addTransform时,就可以得到,而Mi则需要在渲染时获取,bone.getTransformTo(skinnedMesh, Mi) ,
注意对应的Normal变换有点不一样,不是直接的用Mi ,而需要用对应的inverse transpose矩阵:

n‘ = sum [ wi (Mi * Bi)-1Tn ]

Morphing Mesh in M3G

Filed under: Programming

M3G Specification中已有了详细的说明,根据权值对Mesh做简单的变形:

Denoting the base mesh with B, the morph targets with Ti, and the weights corresponding to the morph targets with wi,
the resultant mesh R is computed as follows:

R = B + sum [ w i ( T i - B) ]

我们只要做简单的变化,

R = B + sum[ wi (Ti - B)]

= B + sum(wi * Ti ) - sum(wi * B)

= [1 - sum(wi )] * B + sum(wi * Ti )

这样就容易理解,根据上式也很容易编码。

==============

Kemulator中,是在每次渲染前,根据上式计算出对应的Mesh,如果顶点数比较多,则需要消耗一定的计算时间。
假如遇到有的手机对Morphing Mesh渲染比较慢,就可以考虑自己封装一个Morphing的实现,
当Mesh需要改变时才计算新的mesh,渲染时就不需要额外的计算了。

April 12, 2007

Pos3D to Pos2D in M3G

Filed under: Programming

to 大河马~~emoticon

Camera m_camera; //current camera
Transform m_camTransform; //current camera transform
Transform m_objTransform; //transform of the render obj

void Pos3D2Pos2D(float[] pos3D, float[]pos2D)
{
float pos[] = new float[]{pos3D[0], pos3D[1], pos3D[2], 1}

//get current position
m_objTransform.transform(pos);

//apply camera transform
Transform invTrans = new Transform(m_camTransform);
invTrans.invert();
invTrans.transform(pos);

//get z
float z = -pos[2];
float x = 0;
float y = 0;

//projection
Transform transProjection = new Transform();
camera.getProjection(transProjection);
transProjection.transform(pos);

// NDC to View
x = pos[0] * getWidth()/ (2 * z);
y = pos[1] * getHeight()/ (2 * z);

//convert to screen pos.
pos2D[0] = (int)(getWidth()/2 + x);
pos2D[1] = (int)(getHeight()/2 - y);

}

January 31, 2007

Camera In JSR184

Filed under: Programming

1.Camera类
— Lyo Wu

写完模拟器的M3G部分,早就想写点总结,不写怕要忘了。
那就从最简单的Camera类开始。

Camera类封装了3种投影变换:Generic、Parallel、Perspective。
1)Generic
public void setGeneric(Transform transform)
直接指定一个变换矩阵(Transform类其实就是一个矩阵的封装),可以根据需求任意设置投影矩阵。

2)Parallel
public void setParallel(float fovy, float aspectRatio, float near, float far)
平行投影(正射投影,Orthographic Projection),忽略z轴作用,投影后的物体大小尺寸不变。M3G Specification中已经给出了对应的矩阵(NDC坐标系):
| 2/w 0 0 0 |
| 0 2/h 0 0 |
| 0 0 -2/d -(near+far)/d |
| 0 0 0 1 |
其中,fovy - height of the view volume in camera coordinates。
h = height (= fovy)
w = aspectRatio * h
d = far - near

公式推导:

设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。
近平面距离为n,远平面距离为f,视口宽为w,高为h。
x’ = x
y’ = y
映射到NDC ([-1, 1]),
Px = 2 * x’/ w = 2 * x / w
Py = 2 * y’ / h = 2 * y / h
由于z坐标投影后不参与绘图,用于可见性判断,只要保证Pz与z呈线性关系,即Pz=a*z+b
将(-n,-1), (-f, 1) 代入得
a = -2 / (f - n)
b = -(n + f) / (f - n)
Pz = -2/ (f - n)*z - (n + f) / (f - n)
即等价于
| x || 2/ w 0 0 0 |
| y | | 0 2 / h 0 0 |
| z | * | 0 0 -2/ (f – n) -( n + f) / (f - n)|
| 1 | | 0 0 0 1 |

3)Perspective
public void setPerspective(float fovy, float aspectRatio, float near, float far)
透视投影,即离视点近的物体大,离视点远的物体小,符合人们心理习惯。
M3G Specification中已经给出了对应的矩阵(NDC坐标系):
| 1/w 0 0 0 |
| 0 1/h 0 0 |
| 0 0 -(near+far)/d -2*near*far/d |
| 0 0 -1 0 |
其中,fovy - field of view in the vertical direction, in degrees。
h = tan ( fovy/2 )
w = aspectRatio * h
d = far - near

公式推导:

设(x, y, z, w)为视点坐标,(x’, y’, z’, w’)为投影坐标,(Px, Py, Pz, Pw)为NDC。
近平面距离为n,远平面距离为f,近平面宽为W,高为H。
由相识三角形可以得到
x’ = -n * x / z
y’ = -n * y / z
映射到NDC ([-1, 1]),可得
Px = x’/ (W/2) = -2*n*x / z * W
Py = y’/ (H/2) = -2*n*y / z * H
由于x’, y’与1/ z有线性关系,只要保证Pz与1/z呈线性关系,即Pz=a/z+b
将(-n,-1), (-f, 1) 代入得
a = 2*n*f / f - n
b = f + n / f – n
Pz = 2*n*f / (f - n)*z + (f+n) / (f - n)
由于最后会除以w分量,所以可以把共同项写入w分量:
-zPx = 2*n*x / W
-zPy = 2*n*y / H
-zPz = -2*n*f / (f – n) - (f+n) / (f - n) * z
w = -z
即等价于
| x || 2*n / W 0 0 0 |
| y | | 0 2*n / H 0 0 |
| z | * | 0 0 - (f+n) / (f - n) -2*n*f / (f – n)|
| 1 | | 0 0 -1 0|

引入视角fovy,即:
h = tan ( fovy/2 ) = (H/2) / n = H / 2*n
w = aspectRatio * h = W / 2*n
d = f - n

=============

December 9, 2006

M3G API beta

Filed under: Programming

After monthes coding… the M3G APIs have alomost been implemented in my KEmulator.

next, i will make a general review.

m3g classes


相关文章:

  • 使用c# Mongo Driver 完成嵌套查询
  • 过渡到SSAS之一:简单模型认识
  • 谈谈团队合作中的设计与优化
  • 页面元素的定位scrollintoview
  • C#将子线程附加在当前线程之后执行
  • 过渡到SSAS之二:服务的发布
  • MongoDb 中的PageFilter
  • 新浪换标,也许应该做点什么了
  • 使用joint.js 绘制图
  • myfaces与mojarra(JSF RI)处理空属性类型的不同
  • jsonp 示例
  • 平媒怎么了?
  • The server committed a protocol violation. Section=ResponseHeader Detail=CR must be followed by LF
  • Neubla3中的骨骼动画: CoreAnimation子系统
  • TPL Part 1 Task 的使用
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [笔记] php常见简单功能及函数
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  •  D - 粉碎叛乱F - 其他起义
  • jQuery(一)
  • js中的正则表达式入门
  • Just for fun——迅速写完快速排序
  • JWT究竟是什么呢?
  • Linux中的硬链接与软链接
  • maya建模与骨骼动画快速实现人工鱼
  • MySQL几个简单SQL的优化
  • NSTimer学习笔记
  • Puppeteer:浏览器控制器
  • Vue.js-Day01
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 我的面试准备过程--容器(更新中)
  • ionic异常记录
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​学习一下,什么是预包装食品?​
  • #includecmath
  • $.ajax()方法详解
  • $.each()与$(selector).each()
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • %check_box% in rails :coditions={:has_many , :through}
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (3)llvm ir转换过程
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)ssm高校实验室 毕业设计 800008
  • (力扣)循环队列的实现与详解(C语言)
  • (转)原始图像数据和PDF中的图像数据
  • .net CHARTING图表控件下载地址
  • .NET轻量级ORM组件Dapper葵花宝典
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • .net中的Queue和Stack