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

网站开发包含哪些/自动点击器怎么用

网站开发包含哪些,自动点击器怎么用,网站建设 维护 编程,无敌在线观看免费完整版高清一个月前,想开始看下UE4的源码,刚开始以为有Ogre1.9与Ogre2.1源码的基础 ,应该还容易理解,把源码下起后,发现我还是想的太简单了,UE4的代码量对比Ogre应该多了一个量级,毕竟Ogre只是一个渲染引擎…

  一个月前,想开始看下UE4的源码,刚开始以为有Ogre1.9与Ogre2.1源码的基础 ,应该还容易理解,把源码下起后,发现我还是想的太简单了,UE4的代码量对比Ogre应该多了一个量级,毕竟Ogre只是一个渲染引擎,而UE4包含渲染,AI,网络,编辑器等等,所以要理解UE4的源码,应该带着目地去看,这样容易理解。

  在看UE4提供的ContentExamples例子中,一个树生长的例子感觉不错,与之有关的Spline与SplineMesh组件代码比较独立也很容易理解,刚好拿来移植到Unity5中,熟悉UE4与Unity5这二种引擎,哈哈,如下是现在Unity5中的效果图,其中树苗与管子模型默认都是直的,UE4的效果就不截了,因为移植的还是差了好多,有兴趣的大家可以完善,因为时间和水平,暂时只做到这里了。

  

  如下是改写UE4中的FInterpCurve的C#版InterpCurve,都是泛形版的,在这要说下由于C#泛型对比C++泛形缺少很多功能,如T+T这种,C++在编译时能正确指出是否实现+。而C#就算使用泛形约束,也不能指定实现重载+的类型,然后如局部泛形实例化的功能也没有。可以使用泛形加继承来实现,父类泛形T,子类继承泛形的实例化(A : T[Vector3])来完成类似功能。在这我们不使用这种,使用另外一种把相应具体类型有关的操作用委托包装起来,这样也可以一是用来摆脱具体操作不能使用的局限,二是用来实现C++中的局部泛形实例化。照说C#是运行时生成的泛形实例化代码,应该比C++限制更少,可能是因为C#要求安全型等啥原因吧,只能使用功能有限的泛形约束。  

public class InterpCurve<T>
{public List<InterpCurveNode<T>> Points = new List<InterpCurveNode<T>>();public bool IsLooped;public float LoopKeyOffset;public InterpCurve(int capity = 0){for (int i = 0; i < capity; ++i){this.Points.Add(new InterpCurveNode<T>());}}public InterpCurveNode<T> this[int index]{get{return this.Points[index];}set{this.Points[index] = value;}}public void SetLoopKey(float loopKey){float lastInKey = Points[Points.Count - 1].InVal;if (loopKey < lastInKey){IsLooped = true;LoopKeyOffset = loopKey - lastInKey;}else{IsLooped = false;}}public void ClearLoopKey(){IsLooped = false;}/// <summary>/// 计算当线曲线的切线/// </summary>/// <param name="tension"></param>/// <param name="bStationaryEndpoints"></param>/// <param name="computeFunc"></param>/// <param name="subtract"></param>public void AutoSetTangents(float tension, bool bStationaryEndpoints, ComputeCurveTangent<T> computeFunc,Func<T, T, T> subtract){int numPoints = Points.Count;int lastPoint = numPoints - 1;for (int index = 0; index < numPoints; ++index){int preIndex = (index == 0) ? (IsLooped ? lastPoint : 0) : (index - 1);int nextIndex = (index == lastPoint) ? (IsLooped ? 0 : lastPoint) : (index + 1);var current = Points[index];var pre = Points[preIndex];var next = Points[nextIndex];if (current.InterpMode == InterpCurveMode.CurveAuto|| current.InterpMode == InterpCurveMode.CurevAutoClamped){if (bStationaryEndpoints && (index == 0 ||(index == lastPoint && !IsLooped))){current.ArriveTangent = default(T);current.LeaveTangent = default(T);}else if (pre.IsCurveKey()){bool bWantClamping = (current.InterpMode == InterpCurveMode.CurevAutoClamped);float prevTime = (IsLooped && index == 0) ? (current.InVal - LoopKeyOffset) : pre.InVal;float nextTime = (IsLooped && index == lastPoint) ? (current.InVal + LoopKeyOffset) : next.InVal;T Tangent = computeFunc(prevTime, pre.OutVal, current.InVal, current.OutVal,nextTime, next.OutVal, tension, bWantClamping);current.ArriveTangent = Tangent;current.LeaveTangent = Tangent;}else{current.ArriveTangent = pre.ArriveTangent;current.LeaveTangent = pre.LeaveTangent;}}else if (current.InterpMode == InterpCurveMode.Linear){T Tangent = subtract(next.OutVal, current.OutVal);current.ArriveTangent = Tangent;current.LeaveTangent = Tangent;}else if (current.InterpMode == InterpCurveMode.Constant){current.ArriveTangent = default(T);current.LeaveTangent = default(T);}}}/// <summary>/// 根据当前inVale对应的Node与InterpCurveMode来得到在对应Node上的值/// </summary>/// <param name="inVal"></param>/// <param name="defalutValue"></param>/// <param name="lerp"></param>/// <param name="cubicInterp"></param>/// <returns></returns>public T Eval(float inVal, T defalutValue, Func<T, T, float, T> lerp, CubicInterp<T> cubicInterp){int numPoints = Points.Count;int lastPoint = numPoints - 1;if (numPoints == 0)return defalutValue;int index = GetPointIndexForInputValue(inVal);if (index < 0)return this[0].OutVal;// 如果当前索引是最后索引if (index == lastPoint){if (!IsLooped){return Points[lastPoint].OutVal;}else if (inVal >= Points[lastPoint].InVal + LoopKeyOffset){// Looped spline: last point is the same as the first pointreturn Points[0].OutVal;}}//check(Index >= 0 && ((bIsLooped && Index < NumPoints) || (!bIsLooped && Index < LastPoint)));bool bLoopSegment = (IsLooped && index == lastPoint);int nextIndex = bLoopSegment ? 0 : (index + 1);var prevPoint = Points[index];var nextPoint = Points[nextIndex];//当前段的总长度float diff = bLoopSegment ? LoopKeyOffset : (nextPoint.InVal - prevPoint.InVal);if (diff > 0.0f && prevPoint.InterpMode != InterpCurveMode.Constant){float Alpha = (inVal - prevPoint.InVal) / diff;//check(Alpha >= 0.0f && Alpha <= 1.0f);if (prevPoint.InterpMode == InterpCurveMode.Linear){return lerp(prevPoint.OutVal, nextPoint.OutVal, Alpha);}else{return cubicInterp(prevPoint.OutVal, prevPoint.LeaveTangent, nextPoint.OutVal, nextPoint.ArriveTangent, diff, Alpha);}}else{return Points[index].OutVal;}}/// <summary>/// 因为Points可以保证所有点让InVal从小到大排列,故使用二分查找/// </summary>/// <param name="InValue"></param>/// <returns></returns>private int GetPointIndexForInputValue(float InValue){int NumPoints = Points.Count;int LastPoint = NumPoints - 1;//check(NumPoints > 0);if (InValue < Points[0].InVal){return -1;}if (InValue >= Points[LastPoint].InVal){return LastPoint;}int MinIndex = 0;int MaxIndex = NumPoints;while (MaxIndex - MinIndex > 1){int MidIndex = (MinIndex + MaxIndex) / 2;if (Points[MidIndex].InVal <= InValue){MinIndex = MidIndex;}else{MaxIndex = MidIndex;}}return MinIndex;}public T EvalDerivative(float InVal, T Default, Func<T, T, float, T> subtract, CubicInterp<T> cubicInterp){int NumPoints = Points.Count;int LastPoint = NumPoints - 1;// If no point in curve, return the Default value we passed in.if (NumPoints == 0){return Default;}// Binary search to find index of lower bound of input valueint Index = GetPointIndexForInputValue(InVal);// If before the first point, return its tangent valueif (Index == -1){return Points[0].LeaveTangent;}// If on or beyond the last point, return its tangent value.if (Index == LastPoint){if (!IsLooped){return Points[LastPoint].ArriveTangent;}else if (InVal >= Points[LastPoint].InVal + LoopKeyOffset){// Looped spline: last point is the same as the first pointreturn Points[0].ArriveTangent;}}// Somewhere within curve range - interpolate.//check(Index >= 0 && ((bIsLooped && Index < NumPoints) || (!bIsLooped && Index < LastPoint)));bool bLoopSegment = (IsLooped && Index == LastPoint);int NextIndex = bLoopSegment ? 0 : (Index + 1);var PrevPoint = Points[Index];var NextPoint = Points[NextIndex];float Diff = bLoopSegment ? LoopKeyOffset : (NextPoint.InVal - PrevPoint.InVal);if (Diff > 0.0f && PrevPoint.InterpMode != InterpCurveMode.Constant){if (PrevPoint.InterpMode == InterpCurveMode.Linear){//return (NextPoint.OutVal - PrevPoint.OutVal) / Diff;return subtract(NextPoint.OutVal, PrevPoint.OutVal, Diff);}else{float Alpha = (InVal - PrevPoint.InVal) / Diff;//check(Alpha >= 0.0f && Alpha <= 1.0f);//turn FMath::CubicInterpDerivative(PrevPoint.OutVal, PrevPoint.LeaveTangent * Diff, NextPoint.OutVal, NextPoint.ArriveTangent * Diff, Alpha) / Diff;return cubicInterp(PrevPoint.OutVal, PrevPoint.LeaveTangent, NextPoint.OutVal, NextPoint.ArriveTangent, Diff, Alpha);}}else{// Derivative of a constant is zeroreturn default(T);}}
}
InterpCurve

  实现就是拷的UE4里的逻辑,泛形主要是提供公共的一些实现,下面会放出相应附件,其中文件InterpHelp根据不同的T实现不同的逻辑,UESpline结合这二个文件来完成这个功能。

  然后就是UE4里的SplineMesh这个组件,上面的Spline主要是CPU解析顶点和相应数据,而SplineMesh组件是改变模型,如果模型顶点很多,CPU不适合处理这种,故相应实现都在LocalVertexFactory.usf这个着色器代码文件中,开始以为这个很容易,后面花的时间比我预料的多了不少,我也发现我本身的一些问题,相应矩阵算法没搞清楚,列主序与行主序搞混等,先看如下一段代码。

//如下顶点位置偏移右上前1
float4x4 mx = float4x4(float4(1, 0, 0, 0), float4(0, 1, 0, 0), float4(0, 0, 1, 0), float4(1, 1, 1, 1));
//矩阵左,向量右,向量与矩阵为列向量。
v.vertex = mul(transpose(mx), v.vertex);
//向量左,矩阵右,则向量与矩阵为行向量。
v.vertex = mul(v.vertex, mx);//向量左,矩阵右,([1*N])*([N*X]),向量与矩阵为行向量。
float4x3 mx4x3 = float4x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1),float3(1,1,1));
v.vertex = float4(mul(v.vertex,mx4x3),v.vertex.w);
//矩阵左与向量右,([X*N])*([N*1]) mx3x4 = transpose(mx4x3),表面看矩阵无意义,实际是mx4x3的列向量
float3x4 mx3x4 = float3x4(float4(1, 0, 0, 1), float4(0, 1, 0, 1), float4(0, 0, 1, 1));
v.vertex = float4(mx3x4, v.vertex), v.vertex.w);
//这种错误,mx4x3是由行向量组成,必需放左边才有意义
v.vertex = mul(mx4x3, v.vertex.xyz);
矩阵 向量

  其中,Unity本身用的是列矩阵形式,我们定义一个矩阵向x轴移动一个单位,然后打印出来看下结果就知道了,然后把相应着色器的代码转换到Unity5,这段着色器代码我并不需要改变很多,只需要在模型空间中顶点本身需要做点改变就行,那么我就直接使用Unity5中的SurfShader,提供一个vert函数改变模型空间的顶点位置,后面如MVP到屏幕,继续PBS渲染,阴影我都接着用,如下是针对LocalVertexFactory.usf的简单改版。

Shader "Custom/SplineMeshSurfShader" {Properties{_Color("Color", Color) = (1,1,1,1)_MainTex("Albedo (RGB)", 2D) = "white" {}_Glossiness("Smoothness", Range(0,1)) = 0.5_Metallic("Metallic", Range(0,1)) = 0.0//_StartPos("StartPos",Vector) = (0, 0, 0, 1)//_StartTangent("StartTangent",Vector) = (0, 1, 0, 0)//_StartRoll("StartRoll",float) = 0.0//_EndPos("EndPos",Vector) = (0, 0, 0, 1)//_EndTangent("EndTangent",Vector) = (0, 1, 0, 0)//_EndRoll("EndRoll",float) = 0.0//_SplineUpDir("SplineUpDir",Vector) = (0, 1, 0, 0)//_SplineMeshMinZ("SplineMeshMinZ",float) = 0.0//_SplineMeshScaleZ("SplineMeshScaleZ",float) = 0.0//_SplineMeshDir("SplineMeshDir",Vector) = (0,0,1,0)//_SplineMeshX("SplineMeshX",Vector) = (1,0,0,0)//_SplineMeshY("SplineMeshY",Vector) = (0,1,0,0)
    }SubShader{Tags { "RenderType" = "Opaque" }LOD 200CGPROGRAM// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices#pragma exclude_renderers gles// Physically based Standard lighting model, and enable shadows on all light types#pragma surface surf Standard fullforwardshadows vertex:vert// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0sampler2D _MainTex;float3 _StartPos;float3 _StartTangent;float _StartRoll;float3 _EndPos;float3 _EndTangent;float _EndRoll;float3 _SplineUpDir;float _SplineMeshMinZ;float _SplineMeshScaleZ;float3 _SplineMeshDir;float3 _SplineMeshX;float3 _SplineMeshY;struct Input {float2 uv_MainTex;};half _Glossiness;half _Metallic;fixed4 _Color;float3 SplineEvalPos(float3 StartPos, float3 StartTangent, float3 EndPos, float3 EndTangent, float A){float A2 = A  * A;float A3 = A2 * A;return (((2 * A3) - (3 * A2) + 1) * StartPos) + ((A3 - (2 * A2) + A) * StartTangent) + ((A3 - A2) * EndTangent) + (((-2 * A3) + (3 * A2)) * EndPos);}float3 SplineEvalDir(float3 StartPos, float3 StartTangent, float3 EndPos, float3 EndTangent, float A){float3 C = (6 * StartPos) + (3 * StartTangent) + (3 * EndTangent) - (6 * EndPos);float3 D = (-6 * StartPos) - (4 * StartTangent) - (2 * EndTangent) + (6 * EndPos);float3 E = StartTangent;float A2 = A  * A;return normalize((C * A2) + (D * A) + E);}float4x3 calcSliceTransform(float YPos){float t = YPos * _SplineMeshScaleZ - _SplineMeshMinZ;float smoothT = smoothstep(0, 1, t);//实现基于frenet理论//当前位置的顶点与方向根据起点与终点的设置插值float3 SplinePos = SplineEvalPos(_StartPos, _StartTangent, _EndPos, _EndTangent, t);float3 SplineDir = SplineEvalDir(_StartPos, _StartTangent, _EndPos, _EndTangent, t);//根据SplineDir与当前_SplineUpDir 计算当前坐标系(过程类似视图坐标系的建立)float3 BaseXVec = normalize(cross(_SplineUpDir, SplineDir));float3 BaseYVec = normalize(cross(SplineDir, BaseXVec));// Apply roll to frame around splinefloat UseRoll = lerp(_StartRoll, _EndRoll, smoothT);float SinAng, CosAng;sincos(UseRoll, SinAng, CosAng);float3 XVec = (CosAng * BaseXVec) - (SinAng * BaseYVec);float3 YVec = (CosAng * BaseYVec) + (SinAng * BaseXVec);//mul(transpose(A),B), A为正交矩阵,A由三轴组成的行向量矩阵.    //简单来看,_SplineMeshDir为x轴{1,0,0},则下面的不转换,x轴={0,0,0},y轴=XYec,z轴=YVec//_SplineMeshDir为y轴{0,1,0},则x轴=YVec,y轴={0,0,0},z轴=XYec//_SplineMeshDir为z轴{0,0,1},则x轴=XYec,y轴=YVec,z轴={0,0,0}float3x3 SliceTransform3 = mul(transpose(float3x3(_SplineMeshDir, _SplineMeshX, _SplineMeshY)),float3x3(float3(0, 0, 0), XVec, YVec));//SliceTransform是一个行向量组成的矩阵float4x3 SliceTransform = float4x3(SliceTransform3[0], SliceTransform3[1], SliceTransform3[2], SplinePos);return SliceTransform;}void vert(inout appdata_full v){float t = dot(v.vertex.xyz, _SplineMeshDir);float4x3 SliceTransform = calcSliceTransform(t);v.vertex = float4(mul(v.vertex,SliceTransform),v.vertex.w);}void surf(Input IN, inout SurfaceOutputStandard o) {// Albedo comes from a texture tinted by colorfixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;o.Albedo = c.rgb;// Metallic and smoothness come from slider variableso.Metallic = _Metallic;o.Smoothness = _Glossiness;o.Alpha = c.a;}ENDCG}FallBack "Diffuse"
}
SplineMesh

  树的动画就简单了,对应UE4相应的蓝图实现,自己改写下。

public class VineShow : MonoBehaviour
{public AnimationCurve curve = null;private UESpline spline = null;private UESplineMesh splineMesh = null;// Use this for initializationvoid Start(){spline = GetComponentInChildren<UESpline>();splineMesh = GetComponentInChildren<UESplineMesh>();spline.SceneUpdate();if (curve == null || curve.length == 0){curve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(6, 1));}}// Update is called once per framevoid Update(){float t = Time.time % curve.keys[curve.length - 1].time;var growth = curve.Evaluate(t);float length = spline.GetSplineLenght();var start = 0.18f * growth;float scale = Mathf.Lerp(0.5f, 3.0f, growth);UpdateMeshParam(start * length, scale, ref splineMesh.param.StartPos, ref splineMesh.param.StartTangent);UpdateMeshParam(growth * length, scale, ref splineMesh.param.EndPos, ref splineMesh.param.EndTangent);splineMesh.SetShaderParam();}public void UpdateMeshParam(float key, float scale, ref Vector3 position, ref Vector3 direction){var pos = this.spline.GetPosition(key);var dir = this.spline.GetDirection(key);position = splineMesh.transform.worldToLocalMatrix * InterpHelp.Vector3To4(pos);direction = (splineMesh.transform.worldToLocalMatrix * dir) * scale;}
}
VineShow

  本来还准备完善下才发出来,但是时间太紧,没有时间来完善这个,特此记录下实现本文遇到的相关点供以后查找。

  附件:SplineMeshUE4.zip

转载于:https://www.cnblogs.com/zhouxin/p/5260831.html

http://www.jmfq.cn/news/4807855.html

相关文章:

  • php建设网站所用开发软件/国家免费职业培训平台
  • 佛山专业网站制作设计/重庆seo排名公司
  • 广州大石附近做网站的公司/seo双标题软件
  • 网站规划在网站建设中的作用是/网络营销是什么专业类别
  • 网站被黑是怎么回事/赣州seo推广
  • 怎么做系统网站/上海已经开始二次感染了
  • ui设计做兼职的网站/西安seo全网营销
  • 怎么自己制作网站链接/企业网站建设服务
  • p2p网站的建设/批量优化网站软件
  • dedecms 食品网站模板/互联网广告平台排名
  • 如何通过建设网站赚钱/怎样进行网络营销吸引顾客
  • 开网店要建网站 一起的吗/网站怎么申请怎么注册
  • 深圳北斗部标平台网站建设/网络营销的概念是什么
  • 现在宁波做网站/扬州整站seo
  • ECS 安装wordpress/西安seo诊断
  • 做网站的公司经营范围/网站免费建站app
  • 网站建设策划案/网站大全
  • 武汉网站seo服务/营销策划与运营方案
  • 郑州广告公司网站建设/全网模板建站系统
  • 北京做网站的大公司/自助建站系统下载
  • 怎么做网站数据库/关键词歌词
  • 猎头公司简介/学seo的培训学校
  • 网络广告策划流程/成都网站建设seo
  • 自建网站免费教程/企业网络推广平台
  • 湘潭做网站问下磐石网络/外贸平台
  • 广州做韩国网站/万物识别扫一扫
  • 淘宝api 做网站/代写平台在哪找
  • 做网站和优化共多少钱/网络营销顾问工作内容
  • 南宁怎么做网站/从哪里找网络推广公司
  • 深圳建设网站公/可口可乐网络营销策划方案