Games 103 作业四

2024-02-25 11:36
文章标签 作业 103 games

本文主要是介绍Games 103 作业四,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Games 103 作业四

第四次作业就是流体模拟了,作业中给了若干的实现步骤,以及一些模板代码。

首先第一步,在update函数的开头,加载水面mesh的高度,然后在update的结束时,把计算后的高度更新到mesh中。这个很简单:

void Update () 
{Mesh mesh = GetComponent<MeshFilter> ().mesh;Vector3[] X    = mesh.vertices;float[,] new_h = new float[size, size];float[,] h     = new float[size, size];//TODO: Load X.y into h.for(int i = 0; i < size; i++){for(int j = 0; j < size; j++){h[i, j] = X[i * size + j].y;}}//TODO: Store h back into X.y and recalculate normal.for(int i = 0; i < size; i++){for(int j = 0; j < size; j++){X[i * size + j].y = h[i, j];}}mesh.vertices = X;mesh.RecalculateNormals();
}

第二步,当玩家按下r键时,需要在水面随机落下一个水滴,那么该位置的水面高度需要增加,为了避免水面溢出,还需要把该位置附近的水面高度减小,这样保证整体的水量不变。

if (Input.GetKeyDown ("r")) 
{//TODO: Add random water.int ri = Random.Range(0, size);int rj = Random.Range(0, size);float rh = Random.Range(0.1f, 1.0f);h[ri, rj] += rh;int neighbors = 0;if(ri > 0) neighbors++;if(ri < size - 1) neighbors++;if(rj > 0) neighbors++;if(rj < size - 1) neighbors++;rh /= neighbors;if(ri > 0) h[ri - 1, rj] -= rh;if(ri < size - 1) h[ri + 1, rj] -= rh;if(rj > 0) h[ri, rj - 1] -= rh;if(rj < size - 1) h[ri, rj + 1] -= rh;
}

这个时候不停按r可以看到出现很多小坑,坑里还有个小尖峰:

Games 103 作业四1

下一步,就要把这个变化传递出去,作业里要求使用Neumann Boundaries算法来更新,具体可以参考PPT第25页:

Games 103 作业四2

void Shallow_Wave(float[,] old_h, float[,] h, float [,] new_h)
{		for(int i = 0; i < size; i++){for(int j = 0; j < size; j++){new_h[i, j] = h[i, j] + damping * (h[i, j] - old_h[i, j]);if(i > 0) new_h[i, j] += rate * (h[i - 1, j] - h[i, j]);if(i < size - 1) new_h[i, j] += rate * (h[i + 1, j] - h[i, j]);if(j > 0) new_h[i, j] += rate * (h[i, j - 1] - h[i, j]);if(j < size - 1) new_h[i, j] += rate * (h[i, j + 1] - h[i, j]);}}for(int i = 0; i < size; i++){for(int j = 0; j < size; j++){old_h[i, j] = h[i, j];h[i, j] = new_h[i, j];}}
}

此时按r键就可以看到涟漪了:

Games 103 作业四3

那么接下来,就是要加上水面和方块的交互了。先要找到水面与方块相交的区域,然后计算出它们的low_h,这里计算相交可以使用Unity内置的Bounds.IntersectRay,每个水面格子从底部发射一条射线,然后判断是否和方块的包围盒相交,相交的距离就是low_h。

var go = GameObject.Find(name);
var renderer = go.GetComponent<Renderer>();
var bounds = renderer.bounds;
var pos = go.transform.position;
int grid_x = (int)(pos.x * 10 + size * 0.5f);
int grid_z = (int)(pos.z * 10 + size * 0.5f);
int li = grid_x - 6;
int ui = grid_x + 6;
int lj = grid_z - 6;
int uj = grid_z + 6;for(int i = li; i <= ui; i++)
{for(int j = lj; j <= uj; j++){if (i >= 0 && j >= 0 && i < size && j < size){float dist = 99999;bounds.IntersectRay(new Ray(new Vector3(i * 0.1f - size * 0.05f, 0, j * 0.1f - size * 0.05f),Vector3.up), out dist);low_h[i, j] = dist;}}
}

然后需要计算vh,参考PPT第31页的流程:

Games 103 作业四4

for(int i = 0; i < size; i++)
{for(int j = 0; j < size; j++){if (low_h[i, j] <= new_h[i, j]){b[i, j] = (new_h[i, j] - low_h[i, j]) / rate;cg_mask[i, j] = true;}else{b[i, j] = 0;cg_mask[i, j] = false;vh[i, j] = 0;}}
}Conjugate_Gradient(cg_mask, b, vh, li, ui, lj, uj);

得到vh之后,就可以拿来迭代,计算出最终的new_h了:

Games 103 作业四5

for(int i = 0; i < size; i++)
{for(int j = 0; j < size; j++){if (cg_mask[i, j]){vh[i, j] *= gamma;}}
}for(int i = 0; i < size; i++)
{for(int j = 0; j < size; j++){if(i > 0) new_h[i, j] += rate * (vh[i - 1, j] - vh[i, j]);if(i < size - 1) new_h[i, j] += rate * (vh[i + 1, j] - vh[i, j]);if(j > 0) new_h[i, j] += rate * (vh[i, j - 1] - vh[i, j]);if(j < size - 1) new_h[i, j] += rate * (vh[i, j + 1] - vh[i, j]);}
}

最终的效果如下:

Games 103 作业四6

这篇关于Games 103 作业四的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/745349

相关文章

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

【代码随想录训练营第42期 续Day52打卡 - 图论Part3 - 卡码网 103. 水流问题 104. 建造最大岛屿

目录 一、做题心得 二、题目与题解 题目一:卡码网 103. 水流问题 题目链接 题解:DFS 题目二:卡码网 104. 建造最大岛屿 题目链接 题解:DFS  三、小结 一、做题心得 也是成功补上昨天的打卡了。 这里继续图论章节,还是选择使用 DFS 来解决这类搜索问题(单纯因为我更熟悉 DFS 一点),今天补卡的是水流问题和岛屿问题。个人感觉这一章节题对于刚

Java高级Day38-网络编程作业

112.网络编程作业 //1.使用字符流的方式,编写一个客户端程序和服务器端程序//2.客户端发送"name",服务器端接收到后,返回"我是nova"//3.客户端发送"hobby",服务器端接收到后,返回"编写java程序"//4.不是这两个问题,回复"你说啥呢"​​===============//客户端//===============public class SocketT

0906作业+思维导图梳理

一、作业: 1、创捷一个类似于qq登录的界面 1)源代码 #include "widget.h"#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ui->setupUi(this);//QPushbutton:登录、退出this->join = new QP

图论篇--代码随想录算法训练营第五十二天打卡| 101. 孤岛的总面积,102. 沉没孤岛,103. 水流问题,104.建造最大岛屿

101. 孤岛的总面积 题目链接:101. 孤岛的总面积 题目描述: 给定一个由 1(陆地)和 0(水)组成的矩阵,岛屿指的是由水平或垂直方向上相邻的陆地单元格组成的区域,且完全被水域单元格包围。孤岛是那些位于矩阵内部、所有单元格都不接触边缘的岛屿。 现在你需要计算所有孤岛的总面积,岛屿面积的计算方式为组成岛屿的陆地的总数。 解题思路: 从周边找到陆地,然后通过 dfs或者bfs 将

2024.9.6 作业

1> 手写unique_ptr指针指针 #include <iostream>using namespace std;template <typename T>class my_unique_ptr{public:explicit my_unique_ptr(T *p = nullptr) noexcept // 构造函数{ptr = p;}~my_unique_ptr() noexcep

9月6号作业

1:.h文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QWidget> #include<QIcon> //图标类 #include<QLabel> //标签类 #include<QMovie> //动图类 #include<QLineEdit> //行编辑器类

Flink实例(六十九): flink 作业提交(四)总结

独立集群提交 # 启动集群bin/start-cluster.sh# 提交job./bin/flink run ./examples/batch/WordCount.jar --input hdfs:/user/yuan/input/wc.count --output hdfs:/user/yuan/swwwttt yarn session # 启动集群./bin/

【#第三期实战营闯关作业 ## 茴香豆:企业级知识库问答工具】

今天学习了《 茴香豆:企业级知识库问答工具》这一课,对大模型的应用有了更深得认识。以下是记录本课实操过程及截图: 搭建茴香豆虚拟环境: 输入以下命令 ``studio-conda -o internlm-base -t huixiangdou 成功安装虚拟环境截图 安装茴香豆 cd /root 克隆代码仓库 git clone https://github.com/internlm/h

Quartz 作业调度器

1、Quartz  java实现  注:这里使用的是Quartz1.6.5版本(包:quartz-1.6.5.jar)   [java]  view plain copy //测试main函数   //QuartzTest.java   package quartzPackage;         import java.text.SimpleDateFormat